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

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Mon Apr 28 20:06:24 EDT 2014

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

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.