[plt-scheme] Re: Introducing bindings in a macro
Doug Williams wrote:
> I'd like to introduce bindings in a macro. The commented code for
> with-my-struct is more what I would like to see, but it doesn't work,
> The uncommented code works, but is more complex and, well, uglier. Is
> there a clearer way (i.e. closer to the commented code) to write it?
> ; (define-syntax with-my-struct
> ; (syntax-rules ()
> ; ((with-my-struct s
> ; expr ...)
> ; (let ((a (my-struct-a s))
> ; (b (my-struct-b s))
> ; (c (my-struct-c s)))
> ; expr ...))))
This is analogous to:
(define-syntax with-x
(syntax-rules ()
((with-x e)
(let ((x 'something))
e))))
So (with-x x) --rewrites--> (let ((x 'something)) x) =eval=> 'something,
or so you might think, but the x that was introduced and the x that was
already apparent in the program are not the same x. You could think of
it as (with-x x) --rewrites--> (let ((x1 'something)) x) =eval=> unbound
variable reference: x.
This is a consequence of hygiene. In order to bend/break the hygienic
invariant of expansion you need to resort to heavier machinery, ie. your
working code.
In short, you can't (hygienically) introduce a binding in a macro that
can be referenced by the program. If you want a macro to bind an
identifier that you can reference, you have to "give" the macro the
identifier:
(define-syntax with-x
(syntax-rules ()
((with-x x e)
(let ((x 'something))
e))))
Or:
(define-syntax with-my-struct
(syntax-rules ()
((with-my-struct s (a b c) e0 e1 ...)
(let ((a (my-struct-a s))
(b (my-struct-b s))
(c (my-struct-b s)))
e0 e1 ...))))
David