[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