349 lines
14 KiB
Plaintext
349 lines
14 KiB
Plaintext
|
|
MzScheme version 4.0 is different from previous versions of MzScheme
|
|
in several significant ways:
|
|
|
|
- The documentation has been re-organized and re-written. Instead of
|
|
just reference manuals that occasionally provide examples, our
|
|
documentation is now based on "guides" that provides a friendly
|
|
overview and extensive examples, and then separate "references"
|
|
that provide the details (typically in a more terse, precise
|
|
style).
|
|
|
|
- Pairs created with `cons', `list', `map', etc. are immutable. A
|
|
separate datatype, "mpair", implements mutable pairs, with the
|
|
operations `mcons', `mcar', `mcdr', `set-mcar!', and `set-mcdr!'.
|
|
The identifiers `set-car!' and `set-cdr!' are not bound.
|
|
|
|
See "Immutable and Mutable Pairs" below for more information.
|
|
|
|
- The `mzscheme' command-line syntax has changed. Most notably, if no
|
|
flags are provided:
|
|
|
|
* The first argument, if any, is prefixed with the `-u' flag.
|
|
|
|
* If there are no arguments, `-i' is added to start the
|
|
interactive REPL.
|
|
|
|
See "MzScheme Command Line and Initialization" below for more
|
|
information.
|
|
|
|
- A plain identifier as a module reference now refers to a library
|
|
collection, instead of an interactively declared module. For
|
|
example,
|
|
|
|
(require net/url)
|
|
|
|
is equivalent to the old form
|
|
|
|
(require (lib "url.ss" "net"))
|
|
|
|
See "Module Paths" below for more information.
|
|
|
|
- The `mzscheme' module is no longer the preferred base language for
|
|
PLT Scheme code. The following are the most common languages:
|
|
|
|
* `scheme/base' is the most like `mzscheme' in scale and scope,
|
|
but with some improved syntax and a more consistent set of
|
|
precedures. See "scheme/base" below for more information.
|
|
|
|
* `scheme' builds on `scheme/base', and it is analogous to the
|
|
old "Pretty Big" language. The `scheme' language is the default
|
|
language for using the `mzscheme' REPL.
|
|
|
|
* `scheme/gui' builds on `scheme', adding the MrEd GUI classes
|
|
and functions.
|
|
|
|
Library code should generally start with `scheme/base', which is a
|
|
`mzscheme'-like compromise in terms of size (i.e., code size and
|
|
likelihood of name collisions) and convenience (i.e., the most
|
|
commonly used bindings are available). The `scheme' choice is
|
|
appropriate for programs where the additional functionality of
|
|
`scheme' is likely to be needed or loaded, anyway.
|
|
|
|
- The `#lang' shorthand for `module' is now preferred for a module
|
|
declaration in a file. In "my-library.ss", instead of
|
|
|
|
(scheme my-library scheme/base
|
|
(define my-stuff ....)
|
|
....)
|
|
|
|
write
|
|
|
|
#lang scheme/base
|
|
(define my-stuff ....)
|
|
....
|
|
|
|
Note the absence of the parenthesis wrapping the module content
|
|
(it is terminated by the end-of-file) and the absence of the
|
|
redundant identifier `my-library'.
|
|
|
|
- Under Unix, "~" is no longer automatically expanded to a user's
|
|
home directory. The `expand-path' function takes an optional
|
|
argument to explicitly expand the abbreviation.
|
|
|
|
- Hash table printing is enabled by default.
|
|
|
|
- Graph input syntax, such as `#0=(1 . #0#)' is no longer allowed in
|
|
program syntax parsed by `read-syntax', though it is still allowed
|
|
for `read'.
|
|
|
|
- In fully expanded code, `#%datum' expands to `quote'. When using
|
|
the `mzscheme' language, beware that `if' in expansions is the `if'
|
|
of `scheme/base'. When using the `scheme/base' language, beware
|
|
that `lambda' and `#%app' expand to `#%plain-lambda' and
|
|
`#%plain-app' (which are also the `lambda' and `#%app' of the
|
|
`mzscheme' language). The `require' and `provide' forms expand to
|
|
`#%require' and `#%provide'.
|
|
|
|
- The naming convention for compiled files has changed to preserve
|
|
the original file suffix. For example, the bytecode version of
|
|
"x.ss" is now named "x_ss.zo". The "_loader" protocol for
|
|
native-code extensions is no longer supported.
|
|
|
|
- Windows console binary names are converted like Unix binary names:
|
|
downcased with " " replaced by "-".
|
|
|
|
======================================================================
|
|
Immutable and Mutable Pairs
|
|
======================================================================
|
|
|
|
Making pairs immutable helps prevent security and design holes that
|
|
result form unexpected mutation of lists; Schemers do not usually
|
|
think about lists as mutable, and they wrote code that fails in exotic
|
|
ways if a list is mutated concurrently. For similar reasons, immutable
|
|
lists work better with higher-order contracts.
|
|
|
|
Although this change may sound drastic, our experience to date is that
|
|
uses of mutable pairs are isolated and easy to convert to either
|
|
mpairs or functional style.
|
|
|
|
For compatbility, the `cons' exported by the `r5rs' language module is
|
|
an alias for `mcons', and the various list-consuming and -producing
|
|
functions expetced by `r5rs' also use mutable pairs. Even the `lambda'
|
|
form of `r5rs' converts rest arguments to mutable lists.
|
|
|
|
By default, mutable pairs print using curly braces instead of round
|
|
parentheses:
|
|
|
|
> (car (mcons 1 2))
|
|
car: expects argument of type <pair>; given {1 . 2}
|
|
|
|
The `print-mpair-curly-braces' parameter can be set to #f to disable
|
|
this convention.
|
|
|
|
The `r5rs/init' module sets `print-mpair-curly-braces' to #f, along
|
|
with setting various other reader and printer parameters. Thus,
|
|
|
|
mzscheme -l r5rs/init -i
|
|
|
|
starts an R5RS-friendly REPL.
|
|
|
|
======================================================================
|
|
MzScheme Command Line and Initialization
|
|
======================================================================
|
|
|
|
Many of the old `mzscheme' command-line arguments have been removed.
|
|
For example, the `-F' option to load multiple files is no longer
|
|
available.
|
|
|
|
Previous versions of `mzscheme' required the `-m' and/or `-v' flags to
|
|
suppress the version banner and interactive REPL. Now, the REPL must
|
|
be enabled explicitly using the `-i' flag --- except that `-i' is
|
|
implicit in the case that no command-line arguments are provided.
|
|
|
|
The placement of `-i' relative to other flags matters. For example,
|
|
|
|
mzscheme -l r5rs/init -i
|
|
|
|
starts a REPL with just R5RS, whereas
|
|
|
|
mzscheme -i -l r5rs/init
|
|
|
|
requires the R5RS bindings on top of all the bindings that are
|
|
normally available in the REPL.
|
|
|
|
More generally, starting with an `-l', `-t', or `-u' flag (which
|
|
requires a module) causes `mzscheme' to load only the specified
|
|
module, without first loading the default `scheme' module. Using
|
|
only a `-e', `-f', or `-r' flag (which evaluaes a top-level expression
|
|
or loads a file containing top-level expression), in contrast, causes
|
|
the `scheme' loadule to be loaded first to initialize the top-level
|
|
environment. The ".mzschemerc" start-up file is loaded only just
|
|
before starting a REPL, if any.
|
|
|
|
The default for initializing the top-level environment is the `scheme'
|
|
language module, instead of `mzscheme' or its close analogue
|
|
`scheme/base'. The `scheme' module is analogous to the old "Pretty
|
|
Big" language: in addition to the core forms, it supplies contracts,
|
|
the class system, the unit system, and the pretty printer. More
|
|
precisely, the default module is `scheme/init', which is like
|
|
`scheme', but it installs the pretty printer.
|
|
|
|
======================================================================
|
|
Module Paths
|
|
======================================================================
|
|
|
|
The module identified as `mzscheme' is no longer specially built
|
|
in. Instead, plain identifiers used as module paths are now converted
|
|
to an equivalent `lib' form. For example, `mzscheme' as a module
|
|
reference is the same as `(lib "mzscheme")', and `scheme/base' is the
|
|
same as `(lib "scheme/base").
|
|
|
|
New conventions on `lib' paths apply when the specified path
|
|
has no file suffix:
|
|
|
|
* If `lib' contains a single path element with no file suffix, then
|
|
the element is treated as a collection name, and "main.ss" is the
|
|
library. Consequently, `mzscheme', `(lib "mzscheme")', and `(lib
|
|
"mzscheme/main.ss")' are all equivalent.
|
|
|
|
* If `lib' contains a single string with multiple path elements
|
|
within the string and no file suffix, then a ".ss" suffix is added
|
|
automatically. So, `scheme/pretty', `(lib "scheme/pretty")', and
|
|
`(lib "scheme/pretty.ss")' are all equivalent.
|
|
|
|
* For backward compatibility, if `lib' contains a single string that
|
|
is a single path element with a file suffix, then "mzlib" is used
|
|
as the collection. So, `(lib "a-unit.ss")' is equivalent (as in
|
|
previous version) to `(lib "mzlib/a-unit.ss")'.
|
|
|
|
* Also for backward compatibility, when a `lib' form contains
|
|
multiple strings, they are parsed the old way. So, `(lib "url.ss"
|
|
"net")' is equivalent to `(lib "net/url.ss")' or just `net/url'.
|
|
|
|
Since a plain identifier is a `lib' shorthand, a special syntax is
|
|
needed to access an interactively declared module. In that case, you
|
|
must quote the name:
|
|
|
|
> (module m scheme/base ; = `(lib "scheme/base.ss")'
|
|
(provide x)
|
|
(define x 10))
|
|
> (module n scheme/base
|
|
(require 'm scheme/pretty)
|
|
(pretty-print x))
|
|
> (require 'n)
|
|
|
|
======================================================================
|
|
scheme/base
|
|
======================================================================
|
|
|
|
The `scheme/base' module is intended as a replacement for the
|
|
`mzscheme' module. It provides essentially the same functionality, but
|
|
with some syntactic and name changes.
|
|
|
|
* The syntax of `require' and `provide' form is more composable, and
|
|
it is macro-extensible. For example, the `scheme' form
|
|
|
|
(provide (all-from-except scheme/base random))
|
|
|
|
is translated to `scheme/base' as
|
|
|
|
(provide (except-out (all-from-out scheme/base) random))
|
|
|
|
which composes the `except-out' and `all-form-out' sub-forms.
|
|
|
|
Since `require' and `provide' are macro-extensible, sub-forms like
|
|
`except-out' have transformer bindings. To help avoid conflicts,
|
|
sub-form bindings for `require' tend to end with `-in', and
|
|
sub-form bindings for `provide' tend to end with `-out'.
|
|
|
|
The `require-for-syntax', `require-for-template', etc. forms have
|
|
been replaced with `for-syntax', `for-template', and `for-label'
|
|
sub-forms that can be used within `require' or `provide'.
|
|
|
|
* The `lambda'/`define' and procedure-application forms support
|
|
keyword and optional procedure arguments. The declaration syntax is
|
|
an extension of `opt-lambda'. For example,
|
|
|
|
(define (f x [y 10] #:z z #:w [w 12]) ....)
|
|
|
|
defines a function that takes two required arguments: a normal
|
|
argument `x' and another argument with the keyword #:z. It also
|
|
accepts two optional argument: a normal argument `y' that defaults
|
|
to 10, and an argument with the #:w keyword that defaults to 12.
|
|
|
|
The following calls of `f' are all equivalent:
|
|
|
|
(f 1 #:z 11)
|
|
(f 1 10 #:z 11)
|
|
(f 1 10 #:z 11 #:w 12)
|
|
(f 1 #:w 12 #:z 11)
|
|
(f #:z 11 1)
|
|
(f #:z 11 1 10 #:w 12)
|
|
|
|
Note that keyword-based arguments can be provided in any order,
|
|
relative to each other and to non-keyword arguments. "Rest"
|
|
arguments, such as the `x' in `(lambda x 10)', do not capture
|
|
keyword-based arguments; keyword arguments are completely separate
|
|
from by-position arguments, and a separate "rest"-like facility is
|
|
provided for accepting all provided keyword arguments.
|
|
|
|
* Procedures such as `open-output-file' accept the file-mode
|
|
specification ('text or 'binary) and exists-handling option
|
|
('replace, 'error, etc.) via #:mode and #:exists keyword arguments.
|
|
|
|
* Keywords are not allowed as expressions; that is, a keyword is not
|
|
self-quoting. Keywords are still first-class values, however, and a
|
|
keyword expression can be quoted in the usual way:
|
|
|
|
#:a ; a syntax error
|
|
'#:a ; produces the keyword #:a
|
|
|
|
* The `define-struct' form creates immutable structures by default:
|
|
|
|
(define-struct posn (x y)) ; does not declare `set-posn-x!'
|
|
|
|
Specify the #:mutable optional for either the entire structure type
|
|
or an individual field:
|
|
|
|
(define-struct posn (x y)
|
|
#:mutable) ; => `set-posn-x!' and `set-posn-x!'
|
|
(define-struct posn ([x #:mutable] y) ; => just `set-posn-x!'
|
|
|
|
Use the #:inspector option to specify an inspector, such as
|
|
specifying #f to make the structure type tranparent:
|
|
|
|
(define-struct posn (x y) #:inspector #f)
|
|
|
|
Other keyword options such as #:property and #:procedure enable
|
|
`define-struct' to reflect all of the funtionality of the underlying
|
|
`make-struct-type' function.
|
|
|
|
* One-armed `if' is prohibited; use `when', instead.
|
|
|
|
* Some popular procedures formerly in libraries have been moved into
|
|
`scheme/base', including `filter', `remq', and `regexp-split'.
|
|
|
|
* The result of each expression at the module level is automatically
|
|
printed using `(current-print)'.
|
|
|
|
* For syntax patterns in `syntax-case', `syntax-rules', and
|
|
elsewhere, `_' is a wildcard pattern (matches anything) instead of
|
|
a pattern variable.
|
|
|
|
* The initial transformer environment includes only `syntax-rules',
|
|
`syntax-id-rules', `_', and `...'. Use
|
|
|
|
(require (for-syntax scheme/base))
|
|
|
|
to get `syntax-case' into the transformer environment.
|
|
|
|
* A few syntax-related procedure names are different:
|
|
|
|
syntax-object->datum -> syntax->datum
|
|
datum->syntax-object -> datum->syntax
|
|
module-identifier=? -> free-identifier=?
|
|
module-transformer-identifier=? -> free-transformer-identifier=?
|
|
module-template-identifier=? -> free-template-identifier=?
|
|
module-label-identifier=? -> free-label-identifier=?
|
|
|
|
* The `make-namespace' function always creates an empty
|
|
namespace. The `make-base-namespace' function from the
|
|
`scheme/namespace' library creates a namespace to which
|
|
`scheme/base' is attached, but not required into the top-level
|
|
environment.
|
|
|
|
See also the new `syntax/reflect-namespace' library, which provides
|
|
a syntactic form and function for obtaining a namespace for the
|
|
enclosing module.
|