Yes, that's the intended behavior. Possibly, you're expecting
(require (submod "test.rkt" sub)) to instantiate the submodule at phase 1, since the module was declared at phase level 1 relative to its enclosing module. But the declaration phase level doesn't matter for `require`; it instantiates the `sub` module at phase 0. Since `sub` lives at phase level 1 relative to the enclosing module, the enclosing module lives at phase level -1 relative to the `sub` module. So (require (submod "test.rkt" sub)) uses a phase 0 variable `tbl`: that's +1 (due to `begin-for-syntax`) plus -1 (relative to the submodule). The `print` macro imported with `(require "test.rkt")` accesses a `tbl` variable that lives at phase 1. So, that's why the `print` module doesn't see any changes to the phase 0 `tbl` that `sub` mutates. If you import `(submod "test.rkt" sub)` with `for-syntax`, then `sub` is instantiated at phase 1, and it shares the phase 1 `tbl` with a plain import of "test.rkt": > (require "test.rkt") > (print) #<syntax:/tmp/test.rkt:11:32 x> -> outer > (require (for-syntax (submod "test.rkt" sub))) #<syntax:/tmp/test.rkt:11:32 x> -> outer #<syntax:/tmp/test.rkt:11:32 x> -> inner > (print) #<syntax:/tmp/test.rkt:11:32 x> -> inner At Sat, 12 Apr 2014 16:56:24 -0400, Asumu Takikawa wrote: > Hi all, > > I'm trying to figure out how submodules and compile-time state interact, > in particular when the submodule is in a `begin-for-syntax`. > > Example: https://gist.github.com/takikawa/10555205 (also inlined below) > > As the interaction shows, the submodule can read the compile-time table > but when it tries to modify it, the modifications only appear to be > visible from the submodule and not the outer module. > > Is that the expected behavior? Should I not rely on side effects > persisting between a submodule and its containing module? > > Cheers, > Asumu > > ;;; > > #lang racket > > (require (for-syntax racket/dict syntax/id-table)) > > ;; track stuff in this table > (begin-for-syntax > (define tbl (make-free-id-table))) > > ;; a binding we can use in the table > (define x 3) > (begin-for-syntax (define q-x #'x)) > > (begin-for-syntax > ;; initially set x -> "outer" > (dict-set! tbl q-x "outer") > > (module* sub #f > ;; the submodule sees "outer" > (for ([(k v) (in-dict tbl)]) > (printf "~a -> ~a~n" k v)) > (dict-set! tbl q-x "inner") > ;; the submodule now sees "inner" > (for ([(k v) (in-dict tbl)]) > (printf "~a -> ~a~n" k v)))) > > ;; this macro just prints what's in the table > (define-syntax (print stx) > (syntax-case stx () > [(_) > (for ([(k v) (in-dict tbl)]) > (printf "~a -> ~a~n" k v)) > #'(void)])) > > (provide print) > > ;;; > > $ racket > Welcome to Racket v6.0.1.1. > -> (require "test.rkt") > -> (print) > #<syntax:/tmp/test.rkt:11:32 x> -> outer > -> (require (submod "test.rkt" sub)) > #<syntax:/tmp/test.rkt:11:32 x> -> outer > #<syntax:/tmp/test.rkt:11:32 x> -> inner > -> (print) > #<syntax:/tmp/test.rkt:11:32 x> -> outer > ____________________ > Racket Users list: > http://lists.racket-lang.org/users ____________________ Racket Users list: http://lists.racket-lang.org/users

