MzScheme version 200 is different from previous versions of MzScheme in several significant ways: * The new module system supports top-level, first-order modules that import and export both syntax and run-time variables. The library-collection system now works with the module system. In particular, `require-library' has been replaced by a `require' form. * No object or unit system is built into MzScheme. These have been moved to MzLib-defined syntax modules: "class.ss" (or "class-old.ss"), "unit.ss", and "unitsig.ss" in the "mzlib" collection. For example, to get the old class system, use (require (lib "class-old.ss")) * The core syntax system is hygienic; `define-macro' has been replaced by `define-syntax'. The "defmacro.ss" library in the "mzlib" collection defines `define-macro' for compatibility purposes: (require (lib "defmacro.ss")) IMPORTANT: a macro procedure cannot access global bindings as in previous versions. See the MzLib and MzScheme manuals for details. * Although MzScheme has no class system, there is still a "standard" one (i.e., the one that works with MrEd), and it is different from the previous built-in class system. The principal difference is that classes have fields and methods, and the form of a method definition is syntactically restricted (so that it can be implemented with a per-class procedure instead of a per-object procedure). Syntactically, the new `class' form is substantially different from the old `class' form. The new form is more consistent with the `unit' and `module' syntax, using `define' for method and private field declarations. The "class100.ss" library in MzLib supplies a `class100' form with a syntax similar to the old `class' form, but with a semantics that matches the new `class' form. To make old code work with the new class system: 0. Require the "class.ss" and "class100.ss" libraries. 1. Replace "class" with "class100" (and "class*" with "class100*", etc.). 2. Replace "private" with "private-field". 3. Loop until there are no more syntax errors: - Try to load the code - Read the error message (which provides a source location) - Fix the problem The `send' form works as before, but there is no `ivar' form. Field values are accessed through procedures constructed with `make-class-field-accessor'. Instances are constructed with either `make-object' or the new `instantiate' form; the latter supports by-name initialization arguments. See the MzLib documentation for details. The "class-old.ss" library in MzLib implements precisely the old MzScheme class syntax, but it cannot be used with MrEd classes. * Modules can replace units where units are used merely for namespace control, but `unit' still has its own place: - Implementing parameterized components: The `unit' form separates interface from implementation, unlike `module'. - Encapsulating a program that has "global" state: A unitized program can be instantiated multiple times. - Mutually dependent components: A unit linking graph can be cyclic, while the module dependency graph must form a DAG. A unit or unit signature is typically defined within a module. The module must import the MzLib "unitsig.ss" or "unit.ss" library. The "unit.ss" and "unitsig.ss" libraries implement essentially the same forms as in previous versions of MzScheme, except that variables exported from a unit cannot be mutated, and units can contain references to top-level variables (since `module' already catches free variables). * The `struct' form is gone, replaced by a more flexible `make-struct-type' form. The `define-struct' form has changed. In addition to the old bindings from a `define-struct' declaration like (define-struct ( ...)) binds to expansion-time information about the declaration, and the sub-typing form is (define-struct ( ) ( ...)) where is the from a previous `define-struct' --- not an expression that produces a structure type descriptor. The changes break old code in several ways: - The binding for might collide with other definitions. - Sub-typing declarations must be changed, usually by deleting `struct:'. - Struct instances can be `equal?' only if transparent (see below). The new `define-struct' is slightly less powerful than the old one, though in ways that are unlikely to matter. For example, the new form cannot extend a structure type descriptor that is passed into a procedure. The advantage of the change is that forms like `match' and `shared' can work properly with structures. For example, given the declarations (define-struct a (x y)) (define-struct (b a) (z)) The expression (match .... [($ a pat) ....]) is a syntax error, because the structure type `a' has two fields. But (match .... [($ a pat1 pat2) ....]) (match .... [($ b pat1 pat2 pat3) ....]) both work, and the structure types need not be declared as "transparent" (through a dummy inspector). The `struct' module export form exports the binding as well as the old ones, so that sub-typing declarations and `match' forms work across module boundaries. The `struct' signature form for `unit/sig' introduces expansion-time information into importing units that immitates that of a `define-struct' declaration. The information is currently limited, in that subtyping relations are not exposed and the actual structure type may have more fields than declared in the signature. But `match' works with the partial information, for example, matching on as many fields as declared in the signature. The `define-struct' form also works mostly as before, but also supports an optional inspector expression after the field list. Inspectors provide debugging access, with a custodian-like hierarchy for opacity. The form (define-struct s (f ...)) now creates a type for structs that are effectively opaque. Use (define-struct s (f ...) (make-inspector)) for transparent structs. Finally, structure type properties let a programmer attach static information to a structure type. (For example, using properties, structure-based classes can be implemented more efficiently.) Structure type properties are only available via `make-struct-type'. * The `process', `process*', `process/ports', `process*/ports', `system', and `system*' procedures have been moved to a new MzLib library, "process.ss". MzScheme's new built-in form is `subprocess', which takes the same arguments as `process*/ports'. It returns four values: a subprocess value, an input port or false (the subprocess's stdout, if one was created), an output port or false (the subprocess's stdin), and an input port or false (the subprocess's stderr). The new `subprocess-status' procedure gets the status or return code of the subprocess, and `subprocess-pid' gets its process id. The `process', etc. procedures are implemented in terms of `subprocess'. Consequently, old bugs and gaps in support (especially for Windows) have been eliminated. The `execute' and `execute*' procedures were eliminated entirely. * The new `object-wait-multiple' procedure allows blocking on multiple different types of objects, including semaphores, input ports, output ports, and subprocesses. The set of port reading and writing functions includes new peek functions and new non-blocking read and write functions. The `make-input-port' and `make-output-port' procedures have been replaced `make-custom-input-port' and `make-custom-output-port', which implement a port in terms of non-blocking, string-based operations instead of blocking, character-based operations. * The built-in regular-expression matcher works on input ports (in addition to strings). * The mzc compiler supports a subset of the Gambit-C foreign-function interface. * All of the old #% names are gone, since they are unnecessary with the new module and macro system. However, a few new syntactic forms, which are usually implicit, use #%: `#%app', `#%datum', `#%top', etc. * `global-defined-value' is replaced by `namespace-variable-value' and `namespace-set-variable-value!'. The `defined?' procedure moved to the "etc.ss" MzLib library, renamed as `namespace-defined?'. The `make-global-value-list' procedure is gone, but a new `namespace-mapped-symbols' procedure provides similar functionality. * Compiling an expression no longer links its global-variable references to a particular namespace. Instead, an implicit link phase, at the start of evaluation, connects compiled variable references to actual variables in a specific namespace. * In the "unitsig.ss" library, all `unit-with-signature' names were either replaced by `unit/sig' names or eliminated in favor of existing `unit/sig' names. * Removed constant and keyword attributes of global variables, since they are not needed with the module system. * Moved `send-event' to both MrEd and MzLib's "sendevent.ss". MzLib changes: * "functio.ss" was split into "list.ss" and "etc.ss". * "macro.ss" was merged into "etc.ss", mostly. * "invoke.ss" was merged into "unit.ss" and "unitsig.ss". * "include.ss" is new; it implements the `include' form that used to be restricted to `unit/sig' bodies. * "defstru.ss" was roughly re-implemented in "compat.ss" (and the re-implementation matches the Chez form). * "process.ss" is new. * The default for the whole/fractional-exact-numbers parameter in the "pconvert.ss" library is now #f. Inside MzScheme: * "process" in function, type, and macro names was replaced by "thread". * "manager" in function, type, and macro names was replaced by "custodian". * The functions to make and use input and output ports changed considerably. * scheme_rep() is gone; use the Scheme procedure returned by scheme_builtin_value("read-eval-print-loop") instead. * scheme_add_global_constant(), etc. are gone, since globals have no constant or keyword attributes; use scheme_add_global(), etc. instead. * Many port-related functions were changed. For information about minor changes, see HISTORY.