[racket] Understanding lexical context

From: Sam Tobin-Hochstadt (samth at cs.indiana.edu)
Date: Tue Oct 1 14:13:51 EDT 2013

On Tue, Oct 1, 2013 at 2:01 PM, Greg Hendershott
<greghendershott at gmail.com> wrote:
>
> tl;dr: Can anyone suggest how I could improve my
> understanding of this?  Enough that I could improve Fear of
> Macros and help others, too? Thanks in advance.

If you've read the resources you described, then you're definitely
prepared to read [Macros that work together], which lays out all the
underpinnings of the Racket macro system (and comes with a redex
model).

For this specific macro, here's the answer. In your situation, we can
look at all of the syntax objects you tried, and where they're from
(note that the macro stepper would help you here -- look at the
foreground colors of the identifiers):

`stx`: that's the whole thing, so you're taking the lexical context of
the () around `inner` in the definition of `outer`.  Not what you
want.
`k`: that's the occurrence of `inner` in the definition of `outer`.
Still not what we want.
`a`: that's the occurrence of `get` in the definition of `outer`.
Still not what we want.

`body0`: that's `"hi"`, which is in the _input_ to `outer`. So now we
have lexical context from the use site, which is what we want.  Yay!

However, that's not really the right solution.  What if we abstracted
over `outer`:

    (define-syntax-rule (define-as-hi id) (outer id "hi"))

If we use that, it still won't work, because `"hi"` is now in the
definition of `define-as-hi`, which isn't in the input when you use
the macro.  So the right choice for the lexical context is probably
`b`.

[Macros that work together]: http://www.cs.utah.edu/plt/expmodel-6/

Sam

Posted on the users mailing list.