[racket] datum<->syntax with same context, yet "unbound identifier"

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Wed Nov 21 09:53:47 EST 2012

On Wed, Nov 21, 2012 at 8:33 AM, Greg Hendershott
<greghendershott at gmail.com> wrote:
>> The lexical context you're picking up to put on #'args in the lam
>> macro is the context that's sitting on the parentheses in the first
>> argument to 'lam' in the body of 'expand-to-lam'. that context has no
>> "x" bound.
>
> OK, that explains why x is not bound. Thanks!
>
>> This is the trouble with these kinds of macros: you have to be careful
>> to propagate the correct lexical information thru. In this case, you
>> can either change expand-to-lam to carry its argument's lexical
>> context onto that open paren there or you can change lam to use a
>> different spot to get its lexical information (one that's already
>> being carried thru, eg the context on the actual variables for
>> example).
>
> I want lam to be usable by other macros without the latter needing to
> cooperate explicitly; I want them to "just work". So I prefer the
> second way.

In general when you are picking and moving around lexical context like
this then macros won't "just work", I'm sorry to say. They will need
to be aware of which part of the context is being picked up. Best you
can hope for is "mostly just work". :)

> But isn't that what I'm already doing by supplying #'args to datum->syntax?
>
>   (datum->syntax #'args (append (syntax->datum #'args)))
>
> I don't see how else to get "the context on the actual variables". The
> only other choice seems to be `stx', which also doesn't work.

Syntax objects are ordinary datums (a list in this case) paired with
lexical context information (and other information like src locs, but
lets ignore that part for now). In this case, if you remove the
lexical information (using syntax-e, which is a primitive operation
and one you should build your mental model on) and extract the datum
inside, you'll find that it is a list [*] of syntax objects, one for
each variable. The lexical information on the outer list structure can
be different than the lexical information on those objects inside.

[*]: sometimes you'll get a pair where the cdr position is a syntax
object that wraps another pair (or list) instead of just a list, tho.

>> The model in the JFP paper should shed some light on this, I hope. (I
>> seem to recall you looking at that before?)
>
> I did read it and found it helpful to appreciate what the Racket macro
> system has to do and how. But I guess I didn't grok it enough to be
> able to apply it, here. The lightbulb is flickering but not really on,
> yet.

The macro you've written is actually runnable in the model, I think.

Robby

Posted on the users mailing list.