[racket] local-expand 'module-begin

From: Ryan Culpepper (ryanc at ccs.neu.edu)
Date: Thu Sep 12 16:16:08 EDT 2013

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


Posted on the users mailing list.