My $.02

[ie]r-macro-transformer has a nice property that it allows you to combine orthogonal, generic
tools to write macro transformers, whilst syntax-case forces you to use specialized tools that
can only be used within syntax-case.

Here's "when-not" macro in er-macro-transformer, with Gauche's supporting libraries:

(define-syntax when-not
      (lambda (form rename id=?)
         (match form
            ((_ test expr1 expr ...)
             (quasirename rename
                `(if (not ,test) (begin ,expr1 ,@expr))))))))

Here's syntax-case version:

(define-syntax when-not
    (lambda (x)
      (syntax-case x ()
         ((_ test expr1 expr ...)
          #'(if (not test) (begin expr1 expr ...))))))

er-macro-transformer version uses match macro (Wright's match), and
Gauche's quasirename macro (which applies rename procedure on symbols not unoquoted).
They are not tied to macro system at all---they're generally useful tools.

Most of times, syntax-case will make shorter code, and that makes syntax-case perfect "middle-level"
tool.  I wish it could be deconstructed to orthogonal basic tools.  Could the pattern matcher be
splitted from it?  It seems such a waste if an implementation has to have two set of pattern
matchers, and one of them can only be used with specific macro expanders.
(I know the wrapped syntactic forms require special handling.  But I imagine we could define
a pattern matcher library that can accept wrapped form and bare form, for example.)

On Mon, Oct 21, 2019 at 8:38 AM Marc Nieper-Wißkirchen <> wrote:
Am Mo., 21. Okt. 2019 um 19:26 Uhr schrieb John Cowan <>:
> On Sun, Oct 20, 2019 at 5:15 AM Marc Nieper-Wißkirchen <> wrote:
>> What I wanted to express is that later
>> additions to the R7RS-large might make possibly better
>> abstractions/syntax possible. At least for R7RS-large it does not seem
>> to make sense to me to restrict ourselves to syntax that can be
>> portably implemented with `syntax-rules' until we haven't decided on
>> the macro system of R7RS-large.
> I see your point.  But that will be a hard fight.  How would things be better with syntax-case?  (I am asking for instruction, not rhetorically.)

With a procedural macro system, we have a few more options than with
`syntax-rules' alone. For example, a macro like `keyword-call' cannot
match symbol arguments by name with `syntax-rules' alone. It can only
detect whether symbol arguments are bound-identifier=? or

Depending on how much work we want `keyword-call' to be able to do at
compile-time and depending on how we want to match keyword arguments,
we may want to be able to compare symbol arguments by name (and not as

Lassi mentioned somewhere that the shape of the high-level interface
of this SRFI 177 was partly dictated by the limitations of
`syntax-rules'. Maybe I can answer your question better if we decide
on how we want the interface to look like if don't care whether it can
be implemented with `syntax-rules'.

Another possibility allowed by a sufficiently-rich procedural macro
system could be to declare a new type of identifier binding (apart
from a binding as a variable, a pattern variable, a macro keyword),
e.g. a `keyword' binding. Then, a form like `(keyword-call foo 1 2 a:
3 b: 4)' would be portably possible, where the `keyword-call' macro
would check whether `a:' and `b:' are identifiers bound to keywords so
that the macro knows what are keyword arguments and what are macro

Some of these procedures are extending the `syntax-case' system and
make the above possible:

We cannot look into the future, but if R7RS-large becomes at least as
powerful in the macro department, we may even be able to make SRFI
177's syntax to be as nice as the existing native systems.

>> > Unfortunately, the Chibi syntax-case layer depends on syntactic closures,
>> whereas Chicken and Gauche only provide explicit renaming.  (Syntactic closure support is rare:  MIT, Chibi, Picrin.)
>> What do you mean by "unfortunately"?
> By "unfortunately" I mean that if an implementation of syntax-case could be provided on top of explicit renaming, then the barrier to adopting syntax-case as a standard part of the large language is greatly reduced.
>>  while `syntax-case'
>> cannot be implemented on top of explicit renaming or syntactic
>> closures, it can after slight modifications.
> Do you mean modifications to syntax-case itself, or to the substrate?  And what would those modifications consist of?  We could standardize slightly different versions of either.

I meant modifications of the substrate.

First of all, `define-syntax' has to accept transformers that are just
a procedure taking a single argument (the form that is to be
transformed). In this modified system, the original transformers like
`er-macro-transformer' become forms evaluated at compile time that
evaluate to such single argument procedures.

Secondly, every renamed identifier (through `rename' in
`er-macro-transformer', for example) has to remember the local rename
map. Otherwise things like `datum->syntax' (and thus things like SRFI
99) cannot be implemented. For that, it would be enough that the
substrate provides a procedure like `datum->syntax' that takes a
symbol and an identifier and yields an alias of symbol as if
introduced where the identifier was introduced.

Thirdly, one has to be able to define a new kind of binding, namely
bindings as pattern variables.

Next, the substrate has to allow identifier macros.

Lastly, we need parameter objects containing the macro and the usage
environment at expansion time.

All of these changes/additions are not particularly hard to implement
in a working `er-macro-transformer' system. Except for psychological
reasons, I don't see a barrier. The most costly part may be to
implement the pattern matcher of `syntax-case', but this is the same
matcher needed for `syntax-rules'.

On the other hand, it doesn't seem to be possible to implement
`er-macro-transformer' unmodified and efficiently on a `syntax-case'
system. `er-macro-transformer' misses the `bound-identifier=?'
abstraction (it just uses `eq?') and it forces to completely unwrap
all syntax objects, making it slow.

From a user's point of view, nothing speaks for `er-macro-transformer'
in my opinion if one has access to `syntax-case'.
`ir-macro-transformer' of Chicken is better than
`er-macro-transformer', but it is slow and doesn't do anything better
than `syntax-case'.

Thus, standardizing `er-macro-transformer' does not make sense in my
opinion. If we want to standardize something very low level, it should
be something on top of which things like `syntax-case' can be
implemented and which is implementable by Schemes like Guile, Chez,
etc. as well. However, I don't see a compelling reason for such a
low-level system as people will want/should use a higher level system.

Prof. Dr. Marc Nieper-Wißkirchen

Universität Augsburg
Institut für Mathematik
Universitätsstraße 14
86159 Augsburg

Tel: 0821/598-2146
Fax: 0821/598-2090