Closed bjornkihlberg closed 1 year ago
Since ...
means a literal ellipsis in the template, you need to quote it.
To quote it write (... ...)
.
(define-syntax my-macro
(syntax-rules ()
[(_ args ...)
(letrec-syntax ([f (syntax-rules ()
[(_ x (... ...)) (g x (... ...))])]
[g (syntax-rules ()
[(_ 0) 1337]
[(_ x) x])])
(f args ...))]))
Or maybe bind the ellipsis to ooo
to get something a little more readable:
(define-syntax my-macro
(syntax-rules ()
[(_ args ...)
(with-syntax ([ooo #'(... ...)])
(letrec-syntax ([f (syntax-rules ()
[(_ x ooo) (g x ooo)])]
[g (syntax-rules ()
[(_ 0) 1337]
[(_ x) x])])
(f args ...)))]))
Btw - if I try your initial example in Racket, I get the error:
syntax/loc: no pattern variables before ellipsis in template
at: x
Since the rule of the outer macro is: (syntax-rules () [(_ args ...) more)
the only pattern variable is args
. Since x
is part of the template
(of the outer macro) it is not a pattern variable.
The ... after x is thus a literal ... meant to occur in the template, so it needs to be quoted.
@soegaard Thank you very much!
@soegaard I would just add a small correction for future reference if someone else runs into this.
This doesn't work exactly:
(define-syntax my-macro
(syntax-rules ()
[(_ args ...)
(with-syntax ([ooo #'(... ...)])
(letrec-syntax ([f (syntax-rules ()
[(_ x ooo) (g x ooo)])]
[g (syntax-rules ()
[(_ 0) 1337]
[(_ x) x])])
(f args ...)))]))
You need to use syntax-case
:
(define-syntax (my-macro code)
(syntax-case code ()
[(_ args ...)
(with-syntax ([ooo #'(... ...)])
#'(letrec-syntax ([f (syntax-rules ()
[(_ x ooo) (g x ooo)])]
[g (syntax-rules ()
[(_ 0) 1337]
[(_ x) x])])
(f args ...)))]))
Hello, I am having trouble understanding why some macros allow nested ellipses and some don't.
Here's an example that works, taken from the book:
Here's an example that doesn't work:
Trying to compile this throws
I'm trying to understand why the nested ellipses is rejected in the second example but not the first. Can someone help me understand this?