Next: , Previous: , Up: Program structure   [Index]


5.5 Record-type definitions

Record-type definitions are used to introduce new data types, called record types. Like other definitions, they can appear either at the outermost level or in a body. The values of a record type are called records and are aggregations of zero or more fields, each of which holds a single location. A predicate, a constructor, and field accessors and mutators are defined for each record type.

syntax: define-record-type ⟨name⟩ ⟨constructor⟩ ⟨pred⟩ ⟨field⟩…

Syntax: ⟨name⟩ and ⟨pred⟩ are identifiers. The ⟨constructor⟩ is of the form

(⟨constructor name⟩ ⟨field name⟩ …)

and each ⟨field⟩ is either of the form

(⟨field name⟩ ⟨accessor name⟩)

or of the form

(⟨field name⟩ ⟨accessor name⟩ ⟨modifier name⟩)

It is an error for the same identifier to occur more than once as a field name. It is also an error for the same identifier to occur more than once as an accessor or mutator name.

The define-record-type construct is generative: each use creates a new record type that is distinct from all existing types, including Scheme’s predefined types and other record types—even record types of the same name or structure.

An instance of define-record-type is equivalent to the following definitions:

  • ⟨name⟩ is bound to a representation of the record type itself. This may be a run-time object or a purely syntactic representation. The representation is not utilized in this report, but it serves as a means to identify the record type for use by further language extensions.
  • ⟨constructor name⟩ is bound to a procedure that takes as many arguments as there are ⟨field name⟩s in the (⟨constructor name⟩ …) subexpression and returns a new record of type ⟨name⟩. Fields whose names are listed with ⟨constructor name⟩ have the corresponding argument as their initial value. The initial values of all other fields are unspecified. It is an error for a field name to appear in ⟨constructor⟩ but not as a <field name>.
  • ⟨pred⟩ is bound to a predicate that returns #t when given a value returned by the procedure bound to ⟨constructor name⟩ and #f for everything else.
  • Each ⟨accessor name⟩ is bound to a procedure that takes a record of type ⟨name⟩ and returns the current value of the corresponding field. It is an error to pass an accessor a value which is not a record of the appropriate type.
  • Each ⟨modifier name⟩ is bound to a procedure that takes a record of type ⟨name⟩ and a value which becomes the new value of the corresponding field; an unspecified value is returned. It is an error to pass a modifier a first argument which is not a record of the appropriate type.

For instance, the following record-type definition

(define-record-type ⟨pare⟩
  (kons x y)
  pare?
  (x kar set-kar!)
  (y kdr))

defines kons to be a constructor, kar and kdr to be accessors, set-kar! to be a modifier, and pare? to be a predicate for instances of <pare>.

(pare? (kons 1 2))        ⇒ #t
  (pare? (cons 1 2))        ⇒ #f
  (kar (kons 1 2))          ⇒ 1
  (kdr (kons 1 2))          ⇒ 2
  (let ((k (kons 1 2)))
    (set-kar! k 3)
    (kar k))                ⇒ 3

Next: Libraries, Previous: Syntax definitions, Up: Program structure   [Index]