[R6RS] Eval vs. phases
dyb at cs.indiana.edu
dyb at cs.indiana.edu
Wed Jul 12 12:51:01 EDT 2006
> >> Don't we need to distinguish between expand and run phases *within*
> >> the eval phase?
> > With Model 2, yes, and it's not clear how to do so. This was what I meant
> > by "Unfortunately, this makes eval a bit more difficult to handle, since
> > we'll need some sort of argument or wrapper on the expression passed to
> > eval to specify the meta levels at which the libraries used by the
> > evaluated code are invoked".
> I was thinking less in terms of the semantics of execution, but in
> terms of what's visible. Doesn't that problem remain even in Model 1?
No. I don't see where your confusion lies, but let me try to elaborate
further and see if that helps.
For each library, there's expand-time information (at least a list of the
exported identifiers and the values of the transformers) needed to expand
the code that depends upon it, and there's run-time information (at least
the set of exported variable values) needed at run time by code that
depends upon it. Let's say that a library is "visited" to make the
expand-time information available and "loaded" to make the run-time
information available. Loading a library causes its top-level forms to be
evaluated as well as the values of its exported variables established.
Importing bindings from a library "for expand" causes the library to be
both visited and loaded at compile time. Importing bindings from a
library "for run" causes the library to be visited at compile time and
loaded at run time. Importing bindings from a library "for eval"
causes the library to be both visited and loaded at run time.
With either model, a library needs to be visited at most once in the same
run; for example, importing bindings from a library "for expand" and "for
run" causes the library to be visited only once.
With Model 1, assuming no separate compilation, a library is loaded at
most once per run, and only one set of locations is associated with the
exported variables. Although R6RS won't prescribe a particular
separate-compilation model, it is likely that if a separately compiled
library A imports a library B for both expand and run, B will be loaded
once when A is compiled and again each time A is loaded.
With Model 2, the library is loaded once per specified meta level and a
different set of bindings is created for each meta level. For example, if
a library is imported "for run" (meta level 0) and "for expand" (meta
level 1), it is loaded twice. We don't have a syntax presently for
importing a library for any higher meta levels---a deficiency in the
current library SRFI if we adopt Model 2---so the expand/run example is
the only one I can give at this point. We also have no syntax for
specifying the meta levels at which a library is invoked in eval'd code.
To be fully general, this would have to be a declarative syntax wrapped
around the expression passed to eval.
With Model 2, it makes sense to break loading down into two steps:
(1) loading the code that, when invoked, will evaluate the library's
top-level forms and establish the values of its exported variables at a
given meta level, and (2) invoking this code. Step 1 need not be done
more than once per run.
More information about the R6RS