[racket-dev] make-empty-namespace vs make-base-empty-namespace; ie attaching racket/base does other "stuff"

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Tue Apr 29 16:17:24 EDT 2014

I think improvements would be welcome. Start with a redex model. 

On Apr 29, 2014, at 3:15 PM, Stephen Chang <stchang at ccs.neu.edu> wrote:

> Thanks for the explanation. It all does make sense.
> I guess I'm still unsatisfied because it still feels like there's a
> gap between the namespace "model" as presented by the docs and what
> actually happens. For example, the docs give me the impression that
> you can't require a module unless it's already declared [1].
> In general, I feel that certain terms, eg, namespace, attach, declare,
> instantiate, should have precise technical meanings but are used
> imprecisely in the docs so that I can't form a proper mental model.
> For example, is possible to say "makes it possible to load "m.rkt""
> using the terminology of the docs? Is there ever a state where "m.rkt"
> is "declared" but not "instantiated"?
> I'm willing to work to improve these parts of the docs to make things
> more consistent (if others agree that improvements are needed).
> [1]: http://docs.racket-lang.org/reference/eval-model.html#%28part._module-eval-model%29
> On Mon, Apr 28, 2014 at 8:06 PM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
>> If you start with an empty namespace, then the handful of primitive
>> modules needed to bootstrap `racket/base` are not there. Attaching
>> `racket/base` doesn't make "m.rkt" available, but it makes it possible
>> to load "m.rkt", after which "m.rkt" will be declared in the namespace.
>> It's not a matter of initializing the module name resolver, which is
>> not attached to a namespace. It's just a question of having the
>> necessary primitive modules declared in a namespace.
>> The `'#%builtin` module imports all the primitive modules needed to
>> bootstrap `racket/base` --- that's its job --- while neither
>> `'#%kernel` nor `'#%boot` reach all of the needed primitive modules.
>> Ideally, you wouldn't be able to access any of those modules whose
>> names start "'#%", because you shouldn't use them. I don't know how to
>> hide the modules from you without also hiding them from `racket/base`.
>> When I try
>> (parameterize ([current-namespace (make-base-empty-namespace)])
>>   (namespace-require "m.rkt")
>>   (module-declared? "m.rkt"))
>> then I get #t back, so I'm not sure why you were getting #f... unless
>> you tried
>> (parameterize ([current-namespace (make-base-empty-namespace)])
>>   (namespace-require "m.rkt"))
>> (module-declared? "m.rkt")
>> which would produce #f, because `module-declared?` consults the current
>> namespace.
>> At Mon, 28 Apr 2014 16:48:04 -0400, Vincent St-Amour wrote:
>>> Extra bit of information, this works too:
>>>    #lang racket
>>>    (define ns (make-empty-namespace))
>>>    (namespace-attach-module (current-namespace) ''#%builtin ns)
>>>    (parameterize ([current-namespace ns])
>>>      (namespace-require "m.rkt"))
>>> But replacing ''#%builtin with ''#%kernel or ''#%boot doesn't. Replacing
>>> it with 'racket/base (to end up with the equivalent of
>>> `make-base-empty-namespace') does work.
>>> Vincent
>>> At Mon, 28 Apr 2014 16:38:24 -0400,
>>> Stephen Chang wrote:
>>>> Motivated by some recent email threads, I decided to better understand
>>>> how Racket namespaces work by re-reading some docs but I got confused.
>>>> Paraphrasing the examples from this part of the guide:
>>>> http://docs.racket-lang.org/guide/mk-namespace.html
>>>> the following example fails because the module registry in the
>>>> namespace is empty:
>>>> (parameterize ([current-namespace (make-empty-namespace)])
>>>>  (namespace-require "m.rkt")) ; error
>>>> But the example works if make-base-empty-namespace is used instead:
>>>> (parameterize ([current-namespace (make-base-empty-namespace)])
>>>>  (namespace-require "m.rkt")) ; works
>>>> (Assume the contents of m.rkt is "#lang racket/base" with nothing else.)
>>>> According to the docs, make-base-empty-namespace "attaches"
>>>> racket/base but why does this make "m.rkt" suddenly "available"? There
>>>> seems to be an unexplained gap between to the two examples. (Adding to
>>>> my confusion is that (module-declared? "m.rkt") evaluates to false,
>>>> even in the 2nd case.)
>>>> With help from Vincent, we investigated and speculate that perhaps
>>>> attaching racket/base also runs "boot" from '#%boot, which populates
>>>> current-module-name-resolver, but could not conclude anything
>>>> definitively. Can someone explain what's happening?
>>>> _________________________
>>>>  Racket Developers list:
>>>>  http://lists.racket-lang.org/dev
>>> _________________________
>>>  Racket Developers list:
>>>  http://lists.racket-lang.org/dev
> _________________________
>  Racket Developers list:
>  http://lists.racket-lang.org/dev

Posted on the dev mailing list.