Next: , Up: srfi err5rs records spec   [Index]


2.32.3.1 Procedural layer

The (srfi :99 records procedural) library exports the following procedures.

Function: make-rtd name fieldspecs
Function: make-rtd name fieldspecs parent

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:

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 record–type.

Implementations may wish to extend this procedure to support the non–generative, sealed, and/or opaque features of the R6RS. The recommended way to support those features is to allow any combination of the following arguments to follow the optional parent argument:

The recommendation above is not binding on implementations of SRFI 99. There are other ways to realize sealed, opaque, or non-generative rtds.

Returns an R6RS–compatible record–type descriptor. Could be defined (without the recommended error checking, and without the extensions described above) in terms of the R6RS procedural layer by:

(define (make-rtd name fieldspecs . rest)
  (make-record-type-descriptor
   name
   (if (null? rest) #f (car rest))
   #f #f #f
   (vector-map (lambda (fieldspec)
                 (if (symbol? fieldspec)
                     (list 'mutable fieldspec)
                     fieldspec))
               fieldspecs)))
Function: rtd? obj

Equivalent to the record-type-descriptor? procedure of the R6RS.

Function: rtd-constructor rtd
Function: 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.

NOTE The optional second argument was proposed by Pavel Curtis, and interoperates well with SRFI-9.

Could be defined in terms of the R6RS procedural layer and ERR5RS inspection layer by:

(define (rtd-constructor rtd . rest)
  ; Computes permutation and allocates permutation buffer
  ; when the constructor is created, not when the constructor
  ; is called.  More error checking is recommended.
  (define (make-constructor fieldspecs allnames maker)
    (let* ((k (length fieldspecs))
           (n (length allnames))
           (buffer (make-vector n (unspecified)))
           (reverse-all-names (reverse allnames)))

      (define (position fieldname)
        (let ((names (memq fieldname reverse-all-names)))
          (assert names)
          (- (length names) 1)))

      (let ((indexes (map position fieldspecs)))
        ; The following can be made quite efficient by
        ; hand-coding it in some lower-level language,
        ; e.g. Larceny's mal.  Even case-lambda would
        ; be good enough in most systems.
        (lambda args
          (assert (= (length args) k))
          (for-each (lambda (arg posn)
                      (vector-set! buffer posn arg))
                    args indexes)
          (apply maker (vector->list buffer))))))
  (if (null? rest)
      (record-constructor
       (make-record-constructor-descriptor rtd #f #f))
      (begin (assert (null? (cdr rest)))
             (make-constructor
              (vector->list (car rest))
              (vector->list (rtd-all-field-names rtd))
              (record-constructor
               (make-record-constructor-descriptor rtd #f #f))))))
Function: rtd-predicate rtd

Equivalent to the record–predicate procedure of the R6RS.

Function: rtd-accessor rtd field

field is a symbol that names a field of the record–type described by the record–type descriptor rtd. Return 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.

Function: rtd-mutator rtd field

field is a symbol that names a field of the record–type described by the record–type descriptor rtd. Return 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.


Next: , Up: srfi err5rs records spec   [Index]