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

From: Greg Hendershott (greghendershott at gmail.com)
Date: Wed Nov 21 10:50:16 EST 2012

Thank you.

> The lexical information on the outer list structure can
> be different than the lexical information on those objects inside.

Ah.

By the way, I've read descriptions of syntax objects that list the
accessors, but when it comes to lexical context say "but you don't
really need that".

But how come there isn't an accessor named something like
`syntax-lexical-context'?  To explore, visualize, debug?

(Even if it returned a value that's just some opaque ID, but unique so
it could be compared to other such values.)

On Wed, Nov 21, 2012 at 9:53 AM, Robby Findler
<robby at eecs.northwestern.edu> wrote:
> 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.