On 09/11/2013 01:50 PM, Tero Hasu wrote:
Hello list,
I'm trying to use local-expand within a custom #%module-begin in order
to inspect the expansion and its side effects, but this does not appear
to work in all cases. Am I using local-expand correctly? Are there
restrictions to its ability to handle a module body?
To demonstrate. This code runs OK
#lang racket
(require (for-meta 2 racket/base))
(define x 0)
(begin-for-syntax
(begin-for-syntax
(define x 2)))
but if I instead try to local-expand the same module body with
#lang racket
(module le-lang racket
(provide
(except-out (all-from-out racket) #%module-begin)
(rename-out [module-begin #%module-begin]))
(define-syntax (module-begin stx)
(syntax-case stx ()
((_ . bs)
(local-expand
#'(#%module-begin . bs)
'module-begin null)))))
(module le-module (submod ".." le-lang)
(require (for-meta 2 racket/base))
(define x 0)
(begin-for-syntax
(begin-for-syntax
(define x 2))))
then I get the error
module: duplicate definition for identifier
at: x
in: (define-values (x) (quote 2))
Note that the problem is not restricted to submodules, and it has
nothing to do with the fact that x is defined in two phases. The same
error is raised by this program:
#lang racket/load
(module le-lang racket
(provide
(except-out (all-from-out racket) #%module-begin)
(rename-out [module-begin #%module-begin]))
(define-syntax (module-begin stx)
(syntax-case stx ()
((_ . bs)
(local-expand
#'(#%module-begin . bs)
'module-begin null)))))
(module le-module 'le-lang
(require (for-meta 2 racket/base))
(define x 0)
(begin-for-syntax
(begin-for-syntax
(define y 2))))
I conjecture that maybe the problem is that the module's environment (or
renames?) is not being cleared/reset at all phases when 'local-expand'
returns, only phases 0 and 1. But in a brief search of the expander code
I wasn't able to confirm my guess.
Ryan
____________________
Racket Users list:
http://lists.racket-lang.org/users