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

From: Stephen Chang (stchang at ccs.neu.edu)
Date: Tue Apr 29 15:15:44 EDT 2014

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

Posted on the dev mailing list.