Hi, I have the following code:
#lang racket (require mzlib/defmacro) (defmacro w/uniq (name . body) `(let ([,name (gensym)]) ,@body)) (defmacro in (x . choices) (w/uniq g `(let ([,g ,x]) (or ,@(map (lambda (c) `(eqv? ,g ,c)) choices))))) Naturally, it fails: expand: unbound identifier in module (in phase 1, transformer environment) in: g Additionally defining w/uniq for-syntax fixes it: #lang racket (require mzlib/defmacro (for-syntax racket mzlib/defmacro)) (begin-for-syntax (defmacro w/uniq (name . body) `(let ([,name (gensym)]) ,@body))) (defmacro w/uniq (name . body) `(let ([,name (gensym)]) ,@body)) (defmacro in (x . choices) (w/uniq g `(let ([,g ,x]) (or ,@(map (lambda (c) `(eqv? ,g ,c)) choices))))) I know this is Racket's phase separation working as intended. Now, I appreciate why Racket separates phases as well as the advantages of hygienic macros, but I'm not writing new code. I'm trying to enable existing code* to run natively in Racket and take advantage of its great JIT and some module optimizations (like inlining). Is there any way to hack the first version to work? One option is to build a deeper nest of duplicate macro definitions each time I encounter a new one. It seems possible, and it might even work, but it sounds awful. I've already written a custom reader and have an extensive library of language syntax/parse macros, so I'm open to anything. -Nick * If you're curious, I believe this is the last obstacle in my implementation of Arc as a Racket language. ____________________ Racket Users list: http://lists.racket-lang.org/users