ERR5RS is still being developed, so the specifications described below are subject to change as its standard libraries are revised.
This section describes the (err5rs load)
library.
Loads ERR5RS code from filename, evaluating each form as though it had been entered at the interactive read/eval/print loop.
The load
procedure should be used only at an interactive top
level and in files that will be loaded into an interactive top
level. Calls to the load
procedure have no effect at compile
time, and should not appear in files that will be compiled
separately; use the library
and import
syntaxes instead.
When a procedure is said to be equivalent to an R6RS procedure, the equivalence holds only when all arguments have the properties required of them by the R6RS specification. ERR5RS does not mandate R6RS exception semantics for programs that violate the specification.
This section describes the (err5rs records procedural)
library.
(make-rtd name fieldspecs parent-rtd)
(make-rtd name fieldspecs parent-rtd option …)
name is a symbol, which matters only to the
rtd-name
procedure of the inspection layer.
fieldspecs is a vector of field specifiers, where
each field specifier is one of
(mutable name)
,
where name is a symbol naming the mutable field;
(immutable name)
,
where name is a symbol naming the immutable field.
The optional parent is an rtd or #f
. It is an error for
any of the symbols in fieldspecs to name more than one
of the fields specified by fieldspecs, but the field names
in fieldspecs may shadow field names in the parent rtd.
make-rtd
returns an R6RS-compatible record-type
descriptor.
Larceny allows the following optional arguments to follow the optional parent-rtd argument:
sealed
means the new rtd cannot be used
as the parent of other rtds;
opaque
means the record?
predicate
will not recognize instances of the new rtd;
uid
, followed by another symbol id,
means the new rtd is non-generative with uid id; the
semantics of this extension is the same as in the R6RS.
These Larceny-specific options may be used in any combination, giving Larceny's ERR5RS records the same expressive power as R6RS records, with which they are fully interoperable.
This predicate returns true if and only if its argument
is a record-type descriptor.
rtd?
is equivalent to the record-type-descriptor?
procedure of the R6RS.
(rtd-constructor rtd fieldspecs)
rtd is a record-type descriptor, and fieldspecs is an optional vector of symbols.
If no fieldspecs argument is supplied,
then rtd-constructor
returns a procedure that expects
one argument for each field of the record-type described
by rtd and returns an instance of that record-type
with its fields initialized to the corresponding
arguments.
Arguments that correspond to the fields of the
record-type's parent (if any) come first.
If fieldspecs is supplied, then rtd-constructor
returns a procedure that expects one argument for each
element of fieldspecs and returns an instance of the
record-type described by rtd with the named fields
initialized to the corresponding arguments.
It is an error if some symbol occurs more than once in fieldspecs. Fields of a derived record-type shadow fields of the same name in its parent; the fieldspecs argument cannot be used to initialize a shadowed field.
Equivalent to the record-predicate
procedure of the R6RS.
field is a symbol that names a field of the record-type described by the record-type descriptor rtd. Returns a unary procedure that accepts instances of rtd (or any record-type that inherits from rtd) and returns the current value of the named field.
Fields in derived record-types shadow fields of the same name in a parent record-type.
field is a symbol that names a field of the record-type described by the record-type descriptor rtd. Returns a binary procedure that accepts instances of rtd (or any record-type that inherits from rtd) and a new value to be stored into the named field, performs that side effect, and returns an unspecified value.
Fields in derived record-types shadow fields of the same name in a parent record-type.
This section describes the (err5rs records inspection)
library.
Equivalent to its R6RS namesake.
Equivalent to its R6RS namesake.
Equivalent to the record-type-name
procedure of the R6RS.
Equivalent to the record-type-parent
procedure of the R6RS.
Equivalent to the record-type-field-names
procedure of the R6RS.
(That is, it returns a vector of the symbols that name the fields
of the record-type represented by rtd, excluding the fields of
parent record-types.)
Returns a vector of the symbols that name the fields of
the record-type represented by rtd, including the fields
of its parent record-types, if any, with the fields of
parent record-types coming before the fields of its children,
with each subsequence in the same order as in the vectors
that would be returned by calling rtd-field-names
on rtd and on all its ancestral record-type descriptors.
(rtd-field-mutable? rtd field)
rtd is a record-type descriptor, and field is a
symbol naming a field of the record-type described by rtd.
Returns #t
if the named field is mutable; otherwise returns #f
.
This section describes the (err5rs records syntactic)
library.
The syntactic layer consists of SRFI 9 extended with single inheritance and (optional) implicit naming.
All ERR5RS record-type definitions are generative (unless
Larceny's optional uid
feature is used), but
ERR5RS drops the SRFI 9 restriction to top level, mainly
because the R6RS allows generative definitions wherever
a definition may appear.
The syntax of an ERR5RS record-type definition is
<definition> -> <record type definition> ; addition to 7.1.6 in R5RS <record type definition> -> (define-record-type <type spec> <constructor spec> <predicate spec> <field spec> ...) <type spec> -> <type name> -> (<type name> <parent>) <constructor spec> -> #f -> #t -> <constructor name> -> (<constructor name> <field name> ...) <predicate spec> -> #f -> #t -> <predicate name> <field spec> -> <field name> -> (<field name>) -> (<field name> <accessor name>) -> (<field name> <accessor name> <mutator name>) <parent> -> <expression> <type name> -> <identifier> <constructor name> -> <identifier> <predicate name> -> <identifier> <accessor name> -> <identifier> <mutator name> -> <identifier> <field name> -> <identifier>
The semantics of a record type definition is the same as in SRFI 9: the record type definition macro-expands into a cluster of definitions that
<type name>
as the record-type descriptor
for the new record-type;
#f
);
#f
);
An ERR5RS record type definition extends SRFI 9 with the following additional options:
<parent>
expression is specified, then it must
evaluate to an rtd that serves as the parent record-type
for the record-type being defined.
#f
is specified for the constructor or predicate,
then no constructor or predicate procedure is defined.
(This is useful when the record-type being defined will
be used as an abstract base class.)
#t
is specified for the constructor or predicate,
then the name of the constructor is the type name prefixed
by make-
, and the name of the predicate is the type name
followed by a question mark (?
).
#t
or as an
identifier, then the constructor's arguments correspond
to the fields of the parent (if any) followed by the new
fields added by this record-type definition.
If a field spec consists of a single identifier, then
-
) followed by the field name.
If a field spec consists of a list of one identifier, then
-
) followed by the field name;
-
) followed by the field name followed by -set!
.
Two ERR5RS records with fields are eqv?
if and only if
they were created by the same (dynamic) call to some
record constructor.
Two ERR5RS records are eq?
if and only if they are eqv?
.
Apart from the usual constraint that equivalence according
to eqv?
implies equivalence according to equal?
, the
behavior of equal?
on ERR5RS records is unspecified.
(This is compatible with the R6RS.)
A define-record-type
form macro-expands into code that
calls make-rtd
each time the expanded record-type
definition is executed.
Two ERR5RS record-type descriptors are eqv?
if and only if
they were created by the same (dynamic) call to
make-rtd
.