Support Facilities

14.1  Eval and Load

(eval expr) evaluates expr in the current namespace.46 (See section 8 and section 7.9.1.5 for more information about namespaces.) The 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) is like (eval stx), except that 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 eval.47 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 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 load-relative directory (the value of the 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 load-relative directory is restored to its pre-load value.

(load-relative file-path) is like load, but when file-path is a relative path, it is resolved to an absolute path using the current load-relative directory rather than the current directory. If the current load-relative directory is #f, then load-relative is the same as load.

(load/use-compiled file-path) is like load-relative, but load/use-compiled also checks for .zo files (usually produced with compile-file; see Chapter 12 in PLT MzLib: Libraries Manual) and .so (Unix), .dll (Windows), or .dylib (Mac OS X) files.48 The check for a compiled file occurs whenever 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 system-library-subpath. A compiled file is loaded only if its modification date is not older than the date for 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 load/use-compiled ignores _loader for 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 load-relative directory is set to the directory of the original file-path.

(load/cd file-path) is the same as (load file-path), but load/cd sets both the current directory and current load-relative directory to the directory of 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. When read-eval-print-loop starts, it installs a new error escape procedure (see section 6.7) that does not exit the read-eval-print loop. The read-eval-print-loop procedure does not return until eof is read as an input expression; then it returns void.

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 exit-handler in section 7.9.1.9). The default value for 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 compile-file (see Chapter 12 in PLT MzLib: Libraries Manual) is sufficient for most compilation purposes.

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 read procedure will not parse input beginning with #~ 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 gensym or string->uninterned-symbol. When the compiled object is read via #~, 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 gensym or string->uninterned-symbol to construct an identifier for a top-level or module binding. Instead, generate distinct identifiers either with 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 load-extension for a single extension.

As with load, the current load-relative directory (the value of the 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 load-extension, but it loads an extension with a path that is relative to the current load-relative directory instead of the current directory.

The load-extension 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 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.

14.5  Saving and Restoring Program Images

An image is a memory dump from a running MzScheme program that can be later restored (one or more times) to continue running the program from the point of the dump. Images are only supported for statically-linked Unix versions of MzScheme (and MrEd). There are a few special restrictions on images:

(write-image-to-file file-path [cont-proc]) copies the state of the entire MzScheme process49 to file-path, replacing file-path if it already exists. If images are not supported, the exn:fail:unsupported exception is raised. If cont-proc is #f, then the MzScheme or MrEd process exits immediately after creating the image. Otherwise, cont-proc must be a procedure of no arguments, and the return value(s) of the call to write-image-to-file is (cont-proc). The default value for cont-proc is void.

(read-image-from-file file-path arg-vector) restores the image saved to file-path. Once the image is restored, execution of the original program continues with the return from write-image-to-file; the return value in the restored program is the a vector of strings arg-vector. A successful call to read-image-from-file never returns because the restored program is overlaid over the current program. The vector arg-vector must contain no more than 20 strings, and the total length of the strings must be no more than 2048 characters.

If an error is encountered while reading or writing an image, the exn:fail:filesystem exception is raised or exn:fail exception is raised. Certain errors during read-image-from-file are unrecoverable; in case of such errors, MzScheme prints an error message and exits immediately.

An image can also be restored by starting the stand-alone version of MzScheme or MrEd with the --restore flag followed by the image filename. The return value from write-image-to-file in the restored program is a vector of strings that are the extra arguments provided on the command line after the image filename (if any).


46 The eval procedure actually calls the current evaluation handler (see section 7.9.1.5) to evaluate the expression.

47 The load procedure actually just sets the current load-relative directory and calls the current load handler (see section 7.9.1.6) with file-path to load the file. The description of load here is actually a description of the default load handler.

48 The load/use-compiled 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.

49 The set of environment variables is not saved. When an image is restored, the environment variables of the restoring program are transferred into the restored program.