[racket] Evaluating Racket source files from within another Racket source file

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sun Apr 28 18:01:33 EDT 2013

At Sun, 28 Apr 2013 08:28:46 -0700, Matthew Butterick wrote:
> >
> > The syntax of `enter!' is supposed to be like `require', where the
> > module name is not quoted
> OK, I see what you're saying. And yes, the enter! / require connection is
> noted in the docs.
> As a reader of docs, what trips me up here is that the docs for enter! and
> require both refer to a module-path, but they will not necessarily take as
> input something that returns #t for module-path?, for instance:
> (require "filename.rkt") ; works
> (define name "filename.rkt")
> (module-path? name) ; returns #t
> (require name) ; doesn't work
> However, dynamic-require works differently:
> (define name "filename.rkt")
> (module-path? name) ; returns #t
> (dynamic-require name 'foo) ;works
> I notice that dynamic-require uses the module-path? contract, and enter!
> and require apparently do not. So OK, I guess that's why they can be more
> restrictive. But then when I look up the meaning of module-path?, it says:
> Returns #t if v corresponds to a datum that *matches the grammar for
> module-path for require*, #f otherwise.
> That is, module-path? seems to be defined in terms of what require will
> accept, but in practice module-path? accepts more than require will. Which,
> if true, is strange.

I think you're getting tripped up by the difference between syntax and
values, and also by the way that ' is used in forming module paths.

As Ian says, `enter!' is a syntactic form, and `enter!' is documented
as having the grammar

  (enter! module-path)

The `module-path' here is a syntactic element, and it is defined as a
non-terminal in the definition of `require' (which is why the
documentation of `enter!' refers to `require').

In typical Lispy style, however, we make a connection between a
syntactic module path and a "module-path value": if you take a
syntactic module path and put a quote on the front, you get an
expression whose value is a module-path value --- a value for which
`module-path?' returns #t. In other words, we overload the term "module
path" with different (but related) meanings in syntax and value

Note that if the grammar of `enter!' were

 (enter! expr)

       expr : module-path?

then it would mean that you can put any expression after `enter!', and
the expression's value would be checked at run time to be a module

So, the distinction is carefully and precisely packed in to the
documentation's notation, and programmers don't usually notice this
sort of overloading, because it usually works out in an obvious way.

Unfortunately, the distinction between syntactic module paths and
module-path values can be especially confusing, I think for these

 * Many module paths are just strings, and strings are self-quoting,
   so the syntactic module path and an expression that produces the
   corresponding module path are the same.

 * The form
   is a syntactic module path, and it means "a module with the symbolic
   resolved name `x'".

   At the same time, the form
   is a syntactic module path that means "the main module from the `x'

   A good case can be made that abusing ' for the former module path
   was a bad idea (but it sure is convenient).

 * The *expression*
   produces a value that, when treated as a module path, refers to the
   main module of the `x' collection. 

   To create a value that refers to the module with the symbolic
   resolved name `x', you'd have to write

   That's all consistent --- just put a ' on the front of each example
   from the preceding bullet --- but because ' is used in two different
   ways, it can be confusing.

Finally, I think it's fair to say that the `module-path?' documentation
"a datum that matches the grammar for module-path for require" is too
tightly packed, and we'll improve it.

Posted on the users mailing list.