[plt-scheme] namespace-variable-value

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sun Apr 29 05:03:04 EDT 2007

At Sun, 29 Apr 2007 02:55:03 +0200, Jakub Piotr Cłapa wrote:
> support at taxupdate.com wrote:
> > I hope you don't mind some more questions on this...Why doesn't 
> > namespace-variable-value pick up the mapping in the current-namespace?
> 
> It does. It's just that current-namespace is the top-level namespace and 
> not the module one.
> 
> Why is it so? I don't know and I would love someone to enlighten us on 
> this matter.

The problem is that "namespace" has a very specific meaning in
MzScheme, and it's not a synonym for "lexical context".

Remember that `namespace-variable-value' is just a procedure. It
doesn't matter whether you write

  (module m mzscheme
    (provide nvv)
    (define (nvv id)
      (namespace-variable-value id)))

  (module n mzscheme
    (require m)
    (printf "~s\n" (nvv 'x)))

or

  (module n mzscheme
    (printf "~s\n" (namespace-variable-value 'x)))

or 

  (module m mzscheme
    (provide nvv)
    (define nvv namespace-variable-value))

  (module n mzscheme
    (require m)
    (printf "~s\n" (nvv 'x)))

Since `namespace-variable-value' is a procedure, all of these are the
same --- which is generally what you want for a procedure.

The above examples vary the lexical context of the call to
`namespace-variable-value', but a procedure doesn't see the lexical
context of its call. Indeed, there's a kind of phase separation where
the lexical context matters only for compilation, and it's gone by at
run-time. This separation is crucial to all sorts of compilation and
optimization techniques, to say nothing about your ability to reason
about programs.

Some syntactic forms do inject lexical-context information collected at
compile into run time. For example, `lambda' pays enough attention to
its lexical context to infer a name that is remembered with the
procedure at run-time. Also, `quote-syntax' (and the things built on it),
create a bridge between 

So, if the lexical context is not available at run time, what does
`namespace-variable-value' use? It consults a dynamic entity called a
"namespace", which roughly maps symbols to values. The current
namespace changes only through explicit binding of the
`current-namespace' parameter.


One potentially confusing fact is that there's a connection between
modules and namespace: for every module, there's a namespace that
reflects the bindings that were available at the module's top level.
You can get a module's namespace via `module->namespace'. But I really
mean "reflect" in the sense of "reflection API"; a namespace isn't a
module, nor vice-versa.

The read-eval-print-loop uses this reflective API, of course. I think
it's a bad idea to build anything other debugging and other external
program-manipulation tools on top of the reflective API. My objections
are the same as the standard arguments against using the reflection in
Java. Furthermore, PLT Scheme's syntactic extension means that you
don't have to resort to reflection to accomplish many of things that
are otherwise impossible in Java.

Hope that helps,
Matthew



Posted on the users mailing list.