[R6RS] SYNTAX-CASE
dyb at cs.indiana.edu
dyb
Mon Apr 11 15:46:43 EDT 2005
> I think that naming ellipses avoid confusion. For instance, how would
> you write the following macro in R5Rs pattern matching style:
>
> (define-expander foo
> (lambda (x e)
> (match-case x
> ((?- (bar1 (gee (hux . ?ellipse1) . ?ellipse2) . ?ellipse3)
> (bar2 (gee (hux . ?ellipse4) . ?ellipse5) . ?ellipse6)
> SOMETHING THAT USES ALL THE ELLIPSES
> (else
> ...))))
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
---))
(This is assuming I understand your syntax.)
> It also enlarges the set of transformations you can operate in the results
> of the expansion. In the following example, the ellipses are inverted.
>
> (define-expander flatten
> (lambda (x e)
> (match-case x
> ((?- (foo . ?rest1) (bar . ?rest2))
> (e `(begin , at rest2 , at rest1) e))
> (else
> ...))))
This would be:
(define-syntax flatten
(syntax-rules ()
((_ (foo ...) (bar ...))
(begin bar ... foo ...))))
> Naming ellipses also permits non linear patterns such as:
>
> (define-expander flatten
> (lambda (x e)
> (match-case x
> ((?- (foo . ?rest1) (bar . ?rest1))
> ;; matches if (foo ...) and (bar ...) are equal
> (e `(begin , at rest1) e))
> ((?- (foo . ?rest1) (bar . ?rest2))
> (e `(begin , at rest2 , at rest1) e))
> (else
> ...))))
>
As syntax-case/syntax-rules currently work, you'd need a fender to
do this.
(define-syntax flatten
(syntax-rules ()
((_ (foo ...) (bar ...))
(same? #'(foo ...) #'(bar ...))
(begin foo ...))
((_ (foo ...) (bar ...))
(begin bar ... foo ...))))
same? is easily written using syntax-case.
Of course, we could extend syntax-case/syntax-rules to support your
non-linear patterns, if we decide that this is a sufficiently useful
feature. Then we would have.
(define-syntax flatten
(syntax-rules ()
((_ (foo ...) (foo ...))
(begin foo ...))
((_ (foo ...) (bar ...))
(begin bar ... foo ...))))
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?
(define-syntax let
(syntax-rules ()
((_ ((x e) ...) b1 b2 ...)
((lambda (x ...) b1 b2 ...) e ...))))
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))
Kent
More information about the R6RS
mailing list