[R6RS] syntax-case
dyb at cs.indiana.edu
dyb
Tue Apr 12 11:32:40 EDT 2005
> > In syntax-case or syntax-rules, you name the variable(s) that precede
> > the ellipses, so you would give different names for gee and hux, i.e.,
> >
> > (define-syntax foo
> > (syntax-rules ()
> > ((_ (bar1 (gee1 (hux1 ...) ...) ...)
> > (bar2 (gee2 (hux2 ...) ...) ...))
> > SOMETHING THAT USES ALL THE ELLIPSES
> > ---))
> But this prevents from matching possibly empty lists.
Maybe I'm missing what you mean, but <pat> ... matches zero or more
<pat>s, So (hux1 ...) matches an empty list, (gee1 (hux1 ...) ...) matches
an empty list, and (bar1 (gee1 (hux1 ...) ...) ...) matches an empty list.
> > Do your named ellipses always follow a single pattern variable, or
> > can they follow a subform containing multiple pattern variables which
> > can then be separated in the output, as in the following syntax-rules
> > definition for (unnamed) let?
> Named ellipses can be used anywhere without restrictions. I think that this
> is more powerful even though it might be more verbose in the context of
> macros.
It's not more powerful for writing syntactic extensions, where one has
to wrap the output in a syntax form anyway, and it's less powerful there
since you have to do the mapping explicitly, as your examples illustrate.
> > (define-syntax let
> > (syntax-rules ()
> > ((_ ((x e) ...) b1 b2 ...)
> > ((lambda (x ...) b1 b2 ...) e ...))))
> This example should be written:
>
> (match-case x
> ((?- ?bindings . ?body)
> `((lambda ,(map car bindings) , at body) ,(map cadr bindings))))
So you have to do the mapping explicitly. I certainly prefer not to
have to do so.
> > Also, how would you write the following macro, which requires that one of
> > the inputs (k) and an introduced identifier (*) be replicated as needed
> > to match the number of subforms e ...?
> >
> > (define-syntax distr
> > (syntax-rules ()
> > ((_ k e ...)
> > (+ (* k e) ...))))
> > (distr n a b c) -> (+ (* n a) (* n b) (* n c))
> (match-case x
> ((distr ?k . ?rest)
> `(+ ,@(map (lambda (r) `(* ,k ,r)) rest))))
Again, I prefer the version that does not involve explicit mapping.
> > Here's how I might write something similar using syntax-case in Chez Scheme.
> >
> > (define-syntax +
> > (lambda (x)
> > (import scheme) ; so we can use the built-in +
> > (syntax-case x ()
> > [(_) 0]
> > [(_ x) #'x]
> > [(_ x y)
> > (and (integer? (datum x)) (integer? (datum y)))
> > (+ (datum x) (datum y))]
> > [(k x m ...) #'(+ x (k m ...))])))
> How is the macro expansion prevented from falling into a infinite loop
> while expansing (+ x y) (due to the last clause that introduces a new
> (+ ...)). I'm missing something here.
The (import scheme) makes the built-in + visible, so that the two
occurrences of + in the syntax-case form refer to the built-in +.
The macro plucks the keyword identifier out of the input (as k) to use
for recursion.
Kent
More information about the R6RS
mailing list