[R6RS] syntax-case
Manuel Serrano
Manuel.Serrano
Tue Apr 12 04:27:27 EDT 2005
> > [(+ (and (? integer?) ?v1) (and (? integer?) ?v2)) <expr>]
> >
> > Would you write something such as:
> >
> > [(_ e1 e2) (and (integer? (syntax-object->datum e1) (syntax-object->datum e2))) <expr>]
>
> If I understand your syntax, yes. It would actually look like:
>
> [(_ e1 e2)
> (and (integer? (syntax-object->datum e1))
> (integer? (syntax-object->datum e2)))
> <expr>]
>
> which is what you probably meant.
Yes, of course that's what I meant.
> 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.
> 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.
> (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))))
> 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))))
> > (define-expander +
> > (lambda (x e) ;; x is the form to be macro-expansed, e is an expander
> > (match-case x
> > ((?-)
> > 0)
> > ((?- (and (? integer?) ?v1) (and (? integer?) ?v2))
> > (+ v1 v2))
> > ((?- (and (? fixnum?) ?v1) (and (? fixnum?) ?v2))
> > `(+fixnum ,v1 ,v2))
> > ((?- (and (? flonum?) ?v1) (and (? flonum?) ?v2))
> > `(+flonum ,v1 ,v2))
> > ((?- ?v1 . ?vs)
> > `(+ ,(e v2 e) ,(e `(+ , at vs) e))))))
>
> I don't understand your syntax or perhaps the semantics of your operators.
> It looks like your fixnum case will never be taken, and your fixnum
> and flonum cases might as well do the computation rather than return
> an application. But I think I know what you're getting at.
Yes, you are correct. I wanted to write:
(define-expander +
(lambda (x e) ;; x is the form to be macro-expansed, e is an expander
(match-case x
((?-)
0)
((?- (and (? integer?) ?v1) (and (? integer?) ?v2))
(+ v1 v2))
((?- ?v1 . ?vs)
`(+binary ,(e v2 e) ,(e `(+ , at vs) e))))))
> 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.
Before pursuing with the pattern matching and macros effort, I would like
to hear some opinions. Do you think that we should try to find a unified
mechanism for pattern matching and macro expansion or should we live with
SYNTAX-CASE and, may be, another pattern matching construction. If everyone
here thinks that the current SYNTAX-CASE pattern matching is fine, I would
prefer to same my energy for something else.
--
Manuel
More information about the R6RS
mailing list