I’d like to inject special variables into a macro for compile time binding.
So, for example, the following form:
(define-route (my/route)
(some-proc @@request)
(some-other-proc @@request))
should expand to:
(some-code)
...
(lambda (request)
...
(some-proc request)
(some-other-proc request))
where request is bound to the request in the generated code, at all the places specified by the caller.
I’m not sure how to best go about it. Is this a more common pattern that racket macros provide the ability to do, or do I have to do it manually?
If so, should I recursively loop through the body pattern, looking for any symbols matching ‘@@request and then replace them? I notice that syntax->list isn’t recursive in this way, ie
(syntax->list #'(printf "first: ~a\" (get-var (other-proc)))
is 3 syntax objects not 4, and the third syntax-obj is 2 more. So I assume I need to manually recur here, but maybe there is a better way to do this?
Thanks for your help.
Perhaps using syntax-parameterize (and its variant, splicing-syntax-parameterize) should do the trick? It’s a standard tool when you want to have keyword-like things, and where the macro needs to rewire the keyword’s meaning based on the context.
Here’s what it looks like:
The syntax-parameterization rewires uses of
@@requestin the lexical context of adefine-routeso that it refers back to therequestthat’s being bound by thelambda. If used outside the context of adefine-route, it’ll try to raise a sensible error message.(You could do this the way you initially planned, to recursively walk though the structure of the syntax object and pick out the
@@requestelements. It’s just more work than you need to do, unless the requirements are really unusual.)