Next: , Previous: , Up: The language   [Contents][Index]


5.21 Records

The record is a convenient means of defining structured data types which is similar to C struct. Each record is a distinct data type, meaning that there will only be a single type-predicate matching objects of any individual record type.

All definitions documented in this section are provided by the rep.data.records module (see Modules).

Record types are defined using the define-record-type macro, this in turn defines a number of functions implementing the type. These functions include a constructor, a type predicate, and a user-defined set of field-accessor and -modifier functions.

Macro: define-record-type type (constructor fields…) [predicate] (field accessor [modifier])…

This macro creates a new record type storing an opaque object identifying the type in the variable named type.

It then defines a function constructor with parameter list as specified by the fields…, and a predicate function called predicate if predicate is given.

The fields of the record are defined by the sequence of (field accessor [modifier]) forms, each form describes a single field (named field, which may match one of the constructor arguments).

The function accessor of each field will be defined that when applied to an argument of the record type, returns the value stored in the associated field. If the modifier name is defined a function will be defined of that name, that when applied to a record and an object, stores the object into the associated field of the record.

Note that the fields… may include all the standard lambda-list features (see Lambda Expressions), including keyword parameters and default values.

Here is an example record definition:

(define-record-type :pare
  (kons x y)          ; constructor
  pare?               ; predicate
  (x kar set-kar!)    ; field x, its accessor and modifier
  (y kdr))            ; field y is read-only.

the variable :pare is bound to the record type. Following this definition, the record type could be used as follows:

(define my-kons (kons 1 2))

(pare? my-kons)
    ⇒ t

(kar my-kons)
    ⇒ 1

(set-kar! my-kons 42)

(kar my-kons)
    ⇒ 42

Printed representation of record objects is the name of their type in angle brackets, e.g. for the above pare type, each object prints as the string ‘#<:pare>’. This may be redefined using the define-record-discloser function.

Function: define-record-discloser type discloser

Associate the function discloser with the record type type. When any record of this type is printed, discloser is applied to the object, it should return the value that will actually be printed.

For the above example, the following could be used:

(define-record-discloser :pare (lambda (x) `(pare ,(kar x) ,(kdr x))))

(kons 'a 'b)
    ⇒ (pare a b)

Constructors for records with large numbers of fields often benefit from using keyword parameters. For example the kons record above could be defined as follows (though this would make more sense if it had more than two fields):

(define-record-type :pare
  (kons #!key (kar 1) (kdr 2))
  pare?
  (kar kar set-kar!)
  (kdr kdr set-kdr!))

(kons #:kar 42) ⇒ (pare 42 2)
(kons #:kdr 42) ⇒ (pare 1 42)

Next: , Previous: , Up: The language   [Contents][Index]