[racket] Thought about namespaces

From: Carl Eastlund (cce at ccs.neu.edu)
Date: Sun May 26 14:37:44 EDT 2013

Jos,

When you use make-base-empty-namespace, you get a namespace that shares the
current instantiation of racket/base and nothing else.  When you import
racket using namespace-require, the result is a namespace that shares the
original racket/base but has a fresh copy of everything else from racket.
Since add1 is in racket/base, you will always get the same add1 back from
this process.  Since force is in racket/promise, you will always get a
fresh force back from this process.  If you want a fresh result every time,
you need to start from a purely empty namespace that doesn't even contain
racket/base.  If you want an identical result every time, you need to share
a single instance of all of racket rather than creating a new namespace.

All of this behavior is necessary for the Racket module system to work --
it needs to be possible to share instances sometimes and create fresh ones
others, so when using namespaces and dynamic modules, one always has to be
careful about this.  I don't know of any metaphorical magic wand to wave to
make it easy "most of the time", although of course any suggestions are
welcome.  And I'm sorry if you're mired in it, I know I've struggled with
it rather bitterly more than once.

When I try to repeat this using make-empty-namespace to get a fresh result
every time, I get an error about an unknown module named #%builtin, so I
don't know what needs to be done to make this work.  Still, in principle it
should be doable.

--Carl

On Sun, May 26, 2013 at 1:43 PM, Jos Koot <jos.koot at gmail.com> wrote:

> **
>  #| Consider: |#
>
> #lang racket
>
> (define (get-from-fresh-namespace var)
>  (let ((namespace (make-base-empty-namespace)))
>   (parameterize ((current-namespace namespace))
>    (namespace-require 'racket)
>    (namespace-variable-value var #t (λ () 'error)))))
>
> (eq?
>  (get-from-fresh-namespace 'add1)
>  (get-from-fresh-namespace 'add1)) ; -> #t
>
> (eq?
>  (get-from-fresh-namespace 'force)
>  (get-from-fresh-namespace 'force)) ; -> #f
>
> #|
> It is clear to me why the last form produces #f. Procedure force is a
> predicate of a struct and is exported by module
> .../collects/racket/promise.rkt. For each fresh empty base-namespace the
> form (namespace-require 'racket) uses a distinct instance of this module.
> Each instance defines the promise-struct freshly and provides distinct
> variable- and syntax-bindings related to promises. Is my observation
> correct?
>
> It is little bit confusing that procedure get-from-fresh-namespace, when
> called with the same variable-name, in some cases returns identical values
> and in others does not.
>
> I think it is not easy to make Racket such as to make it procedure
> get-from-fresh-namespace always to return distinct objects (not eq?) or
> always to return identical objects (eq?) when called with the same
> variable-name.
>
> I know, I am comparing procedures, but as
>
> |# (let ((a add1)) (eq? a add1)) #|
>
> is guaranteed to return #t, I wonder what you folks think about to make
> modules such as always provide the same instance of a module when requiredwithin the same Racket or DrRacket session.
> Is it possible? Is it desirable? What when a module produces side effects
> (e.g. displayed output)?
> |#
>
>
>
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130526/f9a1dba0/attachment.html>

Posted on the users mailing list.