[racket] Thought about namespaces
Eric and Carl, thanks very much for your clear replies.
The namespace-anchor with empty namespace (not base) works. I never used
namespace-anchors and shall have to look in the docs to see what exactly
they are.
Thanks, Jos
> -----Original Message-----
> From: Eric Dobson [mailto:eric.n.dobson at gmail.com]
> Sent: domingo, 26 de mayo de 2013 20:38
> To: Jos Koot
> Cc: users at racket-lang.org
> Subject: Re: [racket] Thought about namespaces
>
> Try using make-empty-namespace instead of make-base-empty-namespace.
> It won't work but will explain why the add1 procedures are the same
> when you do get it to work, with the change below.
>
> (define-namespace-anchor anchor)
>
> (define (get-from-fresh-namespace var)
> (let ((namespace (make-empty-namespace)))
> (parameterize ((current-namespace namespace))
> (namespace-attach-module (namespace-anchor->namespace anchor)
> 'racket
> ;''#%builtin
> )
> (namespace-require 'racket)
> (namespace-variable-value var #t (λ () 'error)))))
>
> You are using the the same builtin module instance in your example but
> not the same racket instance. If you use the same racket instance then
> you get the same answer for both values. If you could somehow get a
> different '#%builtin module then the add1's might be different but I
> don't think that is possible.
>
>
> On Sun, May 26, 2013 at 10:43 AM, 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 required
> > within 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
> >
From: carl.eastlund at gmail.com [mailto:carl.eastlund at gmail.com] On Behalf Of
Carl Eastlund
Sent: domingo, 26 de mayo de 2013 20:38
To: Jos Koot
Cc: Racket Users
Subject: Re: [racket] Thought about namespaces
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.