[plt-scheme] Problems with eval

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Fri Jul 4 09:18:50 EDT 2008

Some clarifications:

Libraries should rarely just use the namespace that currently happens
to be installed at the current namespace. When almost all code was in
the `mzscheme' language, just using the current namespace often worked
ok. Now that we have more languages floating around in practice,
though, it's important to keep libraries from stomping on each others'
namespaces (and v4 starts with an empty initial namespace to help
catch problems with using whatever namespace happens to be current).

With that in mind, Robby's example

       #lang scheme
       (namespace-require 'scheme/base)
       (eval '((lambda (x) x) 1))

is fine for a script or for illustrating how to put bindings into a
namespace, but it's almost never the right approach within a library.

It's appropriate to use the current namespace when a library function
is specifically defined to do so. The `compile' and `load' functions,
for example, are supposed to manipulate the current namespace.

But if you're dynamically creating code through `eval' as in Doug's
example, then you want a namespace that's configured in a specific way,
so you should make pick own. Similarly, if you have some code to
macro-expand in the `scheme/base' language, then you should create a
namespace that is initialized with `scheme/base'.


When you pick a namespace explicitly, there are two typical ways to get
it:

 1. Create a fresh one with `make-base-namespace', and initialize it
    further with `namespace-attach-module' and `namespace-require'.
    This gives you the same sort of namespace that you'd get from a
    fresh REPL.

 2. Use `define-namespace-anchor' and `namespace-anchor->namespace'.
    This gives you a namespace that has the same bindings as the
    enclosing module's top level. (Don't use this if you want any
    module-local bindings to be private.)


Matthew



Posted on the users mailing list.