On Sep 3, 2015, at 11:44, Konrad Hinsen <[email protected]> wrote:
> Hi everyone,
>
> Here's another plea for help from the macro experts. I am trying to
> write a macro whose expansion contains another macro, more precisely a
> let-syntax form. My full example is attached below. In the first part,
> I use a let-syntax directly. In the second part, I use a macro that
> generates exactly the form that I wrote by hand in the first part -
> but then the let-syntax seems to be ignored.
>
> The macro stepper isn't of much help here. It shows the expansion
> of (defn (foo2 ...)) into essentially what I wrote by hand for foo1,
> and then declares the expansion finished.
>
> Can anyone tell me (1) why this doesn't work and (2) how to fix it?
It's a capture problem. In the first case, you're just binding the name "send"
locally and all is well. In the second case, you're trying to introduce a
binding for "send" that you didn't get from the input form. You're also getting
a confusing error because "send" is already bound; try using a name that's not
already defined and you should get an unbound identifier.
You can fix this in one of two ways. Your `def' macro could take the name of
the `send' macro it binds as a parameter, which gets a little ugly.
Alternatively, you can use a syntax parameter, which is probably the ideal
solution here.
(require (for-syntax syntax/parse))
(require racket/stxparam)
(define-syntax-parameter send (lambda (stx) (raise-syntax-error 'send "send
used out of context")))
(define-syntax (def stx)
(syntax-parse stx
[(_ (fn-name:id arg:id ...) body ... )
#'(define (fn-name arg ...)
(syntax-parameterize ([send (λ (stx)
(syntax-parse stx
[(send obj:expr method:id x:expr (...
...))
#'(method obj x (... ...))]))])
body ...))]))
(def (foo2 x y)
(send x + y))
(foo2 2 3)
--
Brian Mastenbrook
[email protected]
http://brian.mastenbrook.net/
--
You received this message because you are subscribed to the Google Groups
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.