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

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Wed Nov 21 06:55:14 EST 2012

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.

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).

The model in the JFP paper should shed some light on this, I hope. (I
seem to recall you looking at that before?)

Robby

On Tue, Nov 20, 2012 at 11:39 PM, Greg Hendershott
<greghendershott at gmail.com> wrote:
> I've been struggling to get something working. Jon and Asumu leant me
> a hand on #racket. I learned some ways to use patterns instead of
> resorting to datum->syntax, which I can use in the future. But for
> what I'm doing now (I need to sort arguments for a lambda) I don't see
> any way around running things through syntax->datum and datum->syntax.
> However I seem to be fudging lexical context.
>
> The original is using syntax-parse to chunk up arg specs and so on.
> But, here is a greatly-distilled version:
>
> #lang racket
>
> (require (for-syntax racket/list))
>
> (define-syntax (lam stx)
>   (syntax-case stx ()
>     [(_ args body ...)
>      #`(lambda #,(datum->syntax #'args (append (syntax->datum #'args)))
>          body ...)]))
>
> ;; Use `lam'
> (define f1
>   (lam (x y)
>     (list x y)))
> (f1 1 0)
> ;; => '(1 0)
> ;; Good.
>
> ;; Now a variation:
> (define-syntax (expand-to-lam stx)
>   (syntax-case stx ()
>     [(_ (name arg ...) body ...)
>      #'(lam (arg ...) body ...)]))
>
> ;; Use it
> (expand-to-lam (f2 x y)
>   (list x y))
> ;; =>  x: unbound identifier in module
> ;;       in: x
> ;; Huh?
>
>
> Is there something else I should do instead, or is this possibly a bug?
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Posted on the users mailing list.