Some more excavation into the docs revealed that the preferred technique is to use namespace-require for the initial import only, and then use eval statements for the rest. That helped me resolve a difficult bug. But it didn't resolve this variable-override mystery, because this:
#lang racket (require "x-is-foo.rkt") (displayln x) (define x 'bar) (displayln x) Will throw an "identifier is already imported error." Whereas this: (parameterize ([current-namespace (make-base-empty-namespace)]) (namespace-require 'racket) (eval '(require "x-is-foo.rkt") (current-namespace)) (eval '(displayln x) (current-namespace)) (eval '(define x 'bar) (current-namespace)) (eval '(displayln x) (current-namespace))) Will happily print foo bar So I'm still unclear on the difference in underlying principle that yields the different results. On Tue, May 14, 2013 at 9:09 AM, Matthew Butterick <mb.list.a...@gmail.com>wrote: > Suppose x-is-foo.rkt is this: > > (module x-is-foo racket > (define x 'foo) > (provide x)) > > If you open another file and try this: > > (require "x-is-foo.rkt") > (define x 'bar) > > You'lll get a "identifier already imported" error. OK, that much I > understand. > > Here's the question. When you do this: > > (parameterize ([current-namespace (make-base-empty-namespace)]) > (namespace-require 'racket) > (namespace-require "x-is-foo.rkt") > (namespace-set-variable-value! 'x 'bar) > (eval '(print x) (current-namespace))) > > This time, you get 'foo. Why 'foo? Why not another "identifier already > imported" error? > > I assume I'm missing a subtlety of how the namespace environment is > different. But according to the docs, both namespace-require and > namespace-set-variable-value! affect the top-level environment of the > namespace. So I don't see why the require is silently overriding the > set-variable-value, rather than causing a conflict. > > It's not a sequencing issue, because if you swap the two lines: > > (parameterize ([current-namespace (make-base-empty-namespace)]) > (namespace-require 'racket) > (namespace-set-variable-value! 'x 'bar) > (namespace-require "x-is-foo.rkt") > (eval '(print x) (current-namespace))) > > You still get 'foo. > > Only if you remove the require line: > > (parameterize ([current-namespace (make-base-empty-namespace)]) > (namespace-require 'racket) > (namespace-set-variable-value! 'x 'bar) > (eval '(print x) (current-namespace))) > > Do you get 'bar. > > >
____________________ Racket Users list: http://lists.racket-lang.org/users