[[Err5rsChapter]] ERR5RS standard libraries ------------------------- <> is still being developed, so the specifications described below are subject to change as its standard libraries are revised. [[Err5rsLoadSection]] Load ~~~~ This section describes the `(err5rs load)` library. proc:load[args="filename"] Loads ERR5RS code from _filename_, evaluating each form as though it had been entered at the interactive read/eval/print loop. [WARNING] ================================================================ 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. ================================================================ [[Err5rsRecordsSection]] Records ~~~~~~~ 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. [[Err5rsRecordsProceduralSection]] ==== Procedural layer This section describes the `(err5rs records procedural)` library. proc:make-rtd[args="name fieldspecs",optargs="parent-rtd"] proctempl:make-rtd[args="name fieldspecs parent-rtd"] proctempl:make-rtd[args="name fieldspecs parent-rtd option ..."] _name_ is a symbol, which matters only to the <> procedure of the inspection layer. _fieldspecs_ is a vector of field specifiers, where each field specifier is one of * a symbol naming the (mutable) field; * a list of the form `(mutable _name_)`, where _name_ is a symbol naming the mutable field; * a list of the form `(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. <> returns an R6RS-compatible record-type descriptor. Larceny allows the following optional arguments to follow the optional _parent-rtd_ argument: * the symbol `sealed` means the new rtd cannot be used as the parent of other rtds; * the symbol `opaque` means the <> predicate will not recognize instances of the new rtd; * the symbol `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. proc:rtd?[args="obj"] 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. proc:rtd-constructor[args="rtd"] proctempl:rtd-constructor[args="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. proc:rtd-predicate[args="rtd"] Equivalent to the `record-predicate` procedure of the R6RS. proc:rtd-accessor[args="rtd field"] _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. proc:rtd-mutator[args="rtd field"] _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. [[Err5rsRecordsInspectionSection]] ==== Inspection layer This section describes the `(err5rs records inspection)` library. proc:record?[args="obj"] Equivalent to its R6RS namesake. proc:record-rtd[args="record"] Equivalent to its R6RS namesake. proc:rtd-name[args="rtd"] Equivalent to the `record-type-name` procedure of the R6RS. proc:rtd-parent[args="rtd"] Equivalent to the `record-type-parent` procedure of the R6RS. proc:rtd-field-names[args="rtd"] 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.) proc:rtd-all-field-names[args="rtd"] 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 <> on _rtd_ and on all its ancestral record-type descriptors. proc:rtd-field-mutable?[args="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`. [[Err5rsRecordsSyntacticSection]] ==== Syntactic layer This section describes the `(err5rs records syntactic)` library. The syntactic layer consists of http://srfi.schemers.org/srfi-9/[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 ---------------------------------------------------------------- -> ; addition to 7.1.6 in R5RS -> (define-record-type ...) -> -> ( ) -> #f -> #t -> -> ( ...) -> #f -> #t -> -> -> () -> ( ) -> ( ) -> -> -> -> -> -> -> ---------------------------------------------------------------- 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 * defines the `` as the record-type descriptor for the new record-type; * defines a constructor for instances of the new record-type (unless the constructor spec is `#f`); * defines a predicate that recognizes instances of the new record-type and its subtypes (unless the predicate spec is `#f`); * defines an accessor for each field name; * defines a mutator for each mutable field name. An ERR5RS record type definition extends SRFI 9 with the following additional options: * If a `` expression is specified, then it must evaluate to an rtd that serves as the parent record-type for the record-type being defined. * If `#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.) * If `#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 (`?`). * If the constructor name is specified as `#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 - the field is immutable; - the name of its accessor is the type name followed by a hyphen (`-`) followed by the field name. * If a field spec consists of a list of one identifier, then - the field is mutable; - the name of its accessor is the type name followed by a hyphen (`-`) followed by the field name; - the name of its mutator is the type name followed by a hyphen (`-`) followed by the field name followed by `-set!`. [[RecordIdentitySection]] ==== Record identity 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 <> 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 <>.