[racket-dev] Uninterned symbols in compiled code

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Fri Jul 6 15:04:58 EDT 2012

Thank you, thank you, thank you. I feel really stupid now :-) 
[[ I wrote this kind of macro a couple of weeks ago, and I 
  continually ran into problems. Old man thinking gensym is 
  generate temporary.]]

On Jul 6, 2012, at 2:59 PM, Matthew Flatt wrote:

> I'll push improvements to the cross-reference and explanation in the docs.
> As I try to make an example illustrating problems, I see that Racket is
> more resistant to problems created by `gensym' than I expected. In
> principle, the following is a good example:
> a.rkt:
> ------
> #lang racket
> (define-syntax (define-and-provide stx)
>   (syntax-case stx ()
>     [(_ id)
>      (with-syntax ([ga (gensym 'a)])
>        #'(begin
>            (define ga (random))
>            (define-syntax-rule (id) ga)
>            (provide id)))]))
> (define-and-provide a)
> b.rkt:
> ------
> #lang racket/base
> (require "a.rkt")
> (a)
> After `raco make b.rkt', the compiled form of "b.rkt" will refer to a
> variable whose name is a gensym, and it will be a different gensym than
> the one in "a.rkt" when the latter's code is loaded. The compiled code,
> however, tracks both the name and relative (to other exports) position
> for each variable reference; the linker is happy enough that the
> printed forms of the names match up at the expected export position ---
> which is a leftover from the days when `generate-temporaries' was
> implemented with `gensym'.
> If you throw away the bytecode for "a.rkt" and try to load "b.rkt",
> then you'll most likely get an error, and that error won't happen if
> you use `generate-temporaries'. In other words, the real difference has
> to do with determinism of expansion (as long as everything else in
> expansion is deterministic).

Posted on the dev mailing list.