I'm trying to create a simple nested macro. It works in my Scheme implementation, but fails to run in Guile and Racket.
(define-syntax foo
(syntax-rules (:c)
((_ x ...)
(let-syntax ((bar (syntax-rules ::: (:c)
((_ x)
(print x))
((_ a b :::)
(begin
(display a)
(display " ")
(bar b :::))))))
(bar x ...)))))
- Guile throws:
syntax: missing ellipsis
- Racket throws:
missing ellipsis with pattern variable in template
I've also tried to run in Gambit, but that one just throws:
Unbound variable: define-syntax
I guess you need to use a library to use a basic scheme.
In Checken Scheme, after updating ellipsis:
(define-syntax foo
(syntax-rules (:c)
((_ x ...)
(let-syntax ((bar (syntax-rules <:::> (:c)
((_ x)
(print x))
((_ a b <:::>)
(begin
(display a)
(display " ")
(bar b <:::>))))))
(bar x ...)))))
throws:
template dimension error (too few ellipses?): x
What's wrong with this macro? Why does it throw an error?
EDIT:
It seems that this pattern is not valid:
(_ x ...)
but this is
(_ x y ...)
Is this specified somewhere? Why the first syntax is not valid?
Just to be complete, this code compiles, but why the first doesn't?
(define-syntax foo
(syntax-rules ()
((_ x y ...)
(let-syntax ((bar (syntax-rules <:::> ()
((_ x)
(print x))
((_ a b <:::>)
(begin
(display a)
(display " ")
(bar b <:::>))))))
(bar x y ...)))))
But it doesn't work when tried to use foo macro. It throws:
unbound variable: bar
even when using letrec-syntax.
The problem is that ellipsis are following
xin your outer macro. This means the template that is produced should also have ellipsis followingx, which it doesn't. If you rename the inner macro'sxtoyit should work as you expect.In other words, what you're doing here is equivalent to:
Which wouldn't be allowed either. If you have
xwith ellipsis in the pattern, you must also consume those ellipsis when consumingxin the template that follows it.The reason it works if you make it
(x y ...)is thaty(and its ellipsis rest) is not consumed at all by the template.