Evaluation and Compilation
14.1 Eval and Load
(eval
expr
[namespace
])
evaluates expr
in namespace
, or
in the current namespace if namespace
is not supplied.49 (See section 8 and
section 7.9.1.5 for more information about namespaces.)
The expr
is evaluated in tail position with respect to the
call.
The eval
expr
can be a syntax object, a compiled expression, a
compiled expression wrapped as a syntax object, or an arbitrary
S-expression (which will be converted to a syntax object using
datum->syntax-object
; see section 12.2.2). If expr
is
a syntax object or S-expression, then is enriched with lexical
context using namespace-syntax-introduce
before it is
evaluated. However, if expr
is a pair (or syntax pair) whose
first element is module-identifier=?
to MzScheme's
module
(after giving the identifier context with
namespace-syntax-introduce
), then only the module
identifier is given context, and the rest of expr
is left to
the module's language.
(eval-syntax
stx
[namespace
])
is like (eval
, except that
stx
)stx
must be a syntax object, and its lexical context is not
enriched before it is evaluated.
(load
file-path
)
evaluates each expression in
the specified file using
, wrapping the evaluation in
a continuation prompt (see section 6.5) for the default
continuation prompt tag with handler that
propagates the abort to the continuation of the eval
call.50 The return value from load
is the
value of the last expression from the loaded file (or void if the
file contains no expressions). If load
file-path
is a relative
path, then it is resolved to an absolute path using the
current directory. Before the first expression of file-path
is
evaluated, the current
directory (the value of
the load-relative
current-load-relative-directory
parameter; see
section 7.9.1.6) is set to the absolute
path of the directory containing file-path
; after the last
expression in file-path
is evaluated (or when the load is
aborted), the
directory is restored to its
pre-load-relative
value.load
(load-relative
file-path
)
is like
, but when
load
file-path
is a relative path, it is resolved to an absolute
path using the current
directory rather
than the current directory. If the current load-relative
directory is load-relative
#f
, then
is the same as
load-relative
.load
(load/use-compiled
file-path
)
is like
, but
load-relative
also checks for .zo files (usually
produced with load/use-compiled
; see Chapter 13
in PLT MzLib: Libraries Manual)
and .so (Unix), .dll (Windows), or .dylib
(Mac OS X) files.51 The check for a compiled file occurs
whenever compile-file
file-path
ends with any extension (e.g., .ss or
.scm), and the check consults the subdirectories indicated by
the use-compiled-file-paths
parameter (see
section 7.9.1.6), relative to file-path
.
The subdirectories are checked in order. A .zo version of the
file is loaded if it exists directly in one of the indicated
subdirectories, or a .so/.dll/.dylib version of
the file is loaded if it exists within a native subdirectory
of a use-compiled-file-paths
directory, in an even deeper
subdirectory as named by
. A compiled
file is loaded only if its modification date is not older than the
date for system-library-subpath
file-path
. If both .zo and
.so/.dll/.dylib files are available, the
.so/.dll/.dylib file is used.
Multiple files can be combined into a single
.so/.dll/.dylib file by creating a special
dynamic extension _loader.so, _loader.dll,
or _loader.dylib. When such an extension is present where
a normal .so/.dll/.dylib would be loaded, then
the _loader extension is first loaded. The result returned by
_loader must be a procedure that accepts a symbol. This
procedure will be called with a symbol matching the base part of
file-path
(without the directory path part of the name and
without the filename extension), and the result must be two values;
if #f
is returned as the first result, then
ignores _loader for
load/use-compiled
file-path
and continues as normal. Otherwise, the first return
value is yet another procedure. When this procedure is applied to no
arguments, it should have the same effect as loading
file-path
. The second return value is either a symbol or
#f
; a symbol indicates that calling the returned procedure
has the effect of declaring the module named by the symbol (which is
potentially useful information to a load handler; see
section 5.8).
While a .zo, .so, .dll, or .dylib file is
loaded (or while a thunk returned by _loader is invoked), the
current
directory is set to the directory of
the original load-relative
file-path
.
(load/cd
file-path
)
is the same as (load
,
but file-path
)
sets both the current directory and current
load/cd
directory to the directory of load-relative
file-path
before the file's expressions are evaluated.
(read-eval-print-loop
)
starts a new read
-eval
-print
loop using the current
input, output, and error ports. The read
-eval
-print
loop wraps each evaluation
with a continuation prompt (see section 6.5) using the
default continuation prompt tag and prompt handler. The read
-eval
-print
loop also wraps
the read and print operations with a prompt for the default tag
whose handler ignores abort arguments and continues the loop. The
procedure does not return until read-eval-print-loop
is read as an input expression; then it returns void.eof
The read-eval-print-loop
procedure is parameterized by the
current prompt read handler, the current evaluation handler, and the
current print handler; a custom read
-eval
-print
loop can be implemented as in the
following example (see also section 7.9.1):
(parameterize ([current-prompt-read
my-read] [current-eval
my-eval] [current-print
my-print]) (read-eval-print-loop
))
14.2 Exiting
(exit
[v
])
passes v
on to the current exit handler (see
in section 7.9.1.9). The default value for
exit-handler
v
is #t
. If the exit handler does not escape or terminate
the thread, void is returned.
The default exit handler quits MzScheme (or MrEd), using its argument as the exit code if it is between 1 and 255 inclusive (meaning ``failure''), or 0 (meaning ``success'') otherwise.
When MzScheme is embedded within another application, the default exit handler may behave differently.
14.3 Compilation
Normally, compilation happens automatically: when syntax is evaluated,
it is first compiled and then the compiled code is executed.
However, MzScheme can also write and read compiled code. MzScheme can
read compiled code much faster than reading syntax and compiling it,
so compilation can be used to speed up program loading. The MzLib
procedure
(see Chapter 13
in PLT MzLib: Libraries Manual) is
sufficient for most compilation purposes.
compile-file
(compile
expr
)
returns a compiled expression forexpr
such that(eval (compile
is the same asexpr
))(eval
. More precisely,expr
)compile
calls the current compilation handler (see section 7.9.1.5) to compileexpr
.(compile-syntax
stx
)
returns a compiled expression forstx
such that(eval (compile-syntax
is the same asstx
))(eval-syntax
.stx
)(compiled-expression?
v
)
returns#t
ifv
is a compiled expression,#f
otherwise.
When a compiled expression is written to an output port, the written
form starts with #~
. These expressions are essentially
assembly code for the MzScheme interpreter, and reading such an
expression produces a compiled expression.
When a compiled expression contains syntax object constants, the
#~
form of the expression drops location information and
properties for the syntax objects (see section 12.2 and
section 12.6.2).
The
procedure will not parse input beginning with
read
#~
unless the read-accept-compiled
parameter (see
section 7.9.1.3) is set to true. When the default
load handler is used to load a file, compiled-expression reading is
automatically (temporarily) enabled as each expression is read.
Compiled code parsed from #~
may contain references to
unexported or protected bindings from a module. At read time, such
references are associated with the current code inspector (see
section 7.9.1.8), and the code will only execute if
that inspector controls the relevant module invocation (see
section 9.4).
A compiled-expression object may contain uninterned symbols (see
section 3.7) that were created by
or
gensym
. When the compiled object is read
via string->uninterned-symbol
#~
, each uninterned symbol in the original expression is
mapped to a new uninterned symbol, where multiple instances of a
single symbol are consistently mapped to the same new symbol. The
original and new symbols have the same printed representation.
Due to the above restrictions, do not use
or
gensym
to construct an identifier for a
top-level or module binding. Instead, generate distinct identifiers
either with string->uninterned-symbol
generate-temporaries
(see section 12.2.2) or by
applying the result of make-syntax-introducer
(see
section 12.6) to an existing identifier.
14.4 Dynamic Extensions
A dynamically-linked extension library is loaded into MzScheme with
(load-extension
file-path
)
. The separate document
Inside PLT MzScheme contains information about writing MzScheme
extensions. An extension can only be loaded once during a MzScheme
session, although the extension-writer can provide functionality to
handle extra calls to
for a single extension.load-extension
As with
, the current load
directory (the
value of the load-relative
current-load-relative-directory
parameter;
see section 7.9.1.6) is set while the
extension is loaded. The load-relative-extension
procedure
is like
, but it loads an extension with a
path that is relative to the current load-extension
directory instead of the current directory.load-relative
The
procedure actually just dispatches to the
current load extension handler (see
section 7.9.1.6). The result of calling
load-extension
is determined by the extension. If the extension
cannot be loaded, the load-extension
exn:fail:filesystem
exception is raised, and if the load
fails because the extension has the wrong version, more specifically the
exn:fail:filesystem:version
exception is raised.
49 The
procedure actually calls the
current evaluation handler (see section 7.9.1.5) to evaluate
the expression.eval
50 The
procedure actually just sets the current load
directory and calls the current load handler (see
section 7.9.1.6) with load-relative
file-path
to load the file. The
description of
here is actually a description of the
default load handler.load
51 The
procedure actually just calls the current load/use-compiled handler
(see section 7.9.1.6). The default handler, in
turn, calls the load or load-extension handler, depending on the type
of file that is loaded.load/use-compiled