#
Chapter 14
Support Facilities

## 14.1 Eval and Load

`(eval``` `expr``)` evaluates `expr` in the current namespace.48 (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``.49 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 11 in PLT MzLib: Libraries Manual) and `.so` (Unix), `.dll` (Windows), or `.dylib` (Mac OS X) files.50 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 11 in PLT MzLib: Libraries Manual) is sufficient for most compilation purposes.

- `(compile``` `expr``)` returns a compiled expression for `expr` such that `(eval (compile `expr`))` is the same as `(eval `expr`)`. More precisely, `compile` calls the current compilation handler (see section 7.9.1.5) to compile `expr`.

- `(compile-syntax``` `stx``)` returns a compiled expression for `stx` such that `(eval (compile-syntax `stx`))` is the same as `(eval-syntax `stx`)`.

- `(compiled-expression?``` `v``)` returns `#t` if `v` 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 ``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:

- All files, TCP connections, and UDP connections must be closed when an image is created.

- No dynamic extensions can be loaded before an image is created.

- No operating system subprocesses can be active when an image is created.

`(write-image-to-file``` `file-path``` [`cont-proc`]`)` copies the state of the entire MzScheme process 51 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).

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

49 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.

50 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.

51 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.