[racket-dev] Uninterned symbols in compiled code
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).