On this page:
define-record-type
define-record-setter
2.3.1 Record Type Information
record-type?
record-type
record-type-name
record-type-fields
record-type-predicate-name
record-type-constructor-name
record-type-accessor-name
2.3.2 Record Type Descriptors
record-descriptor?
initialized-record-descriptor?
uninitialized-record-descriptor?
make-record-implementation
record-descriptor-type
record-descriptor-predicate
record-descriptor-constructor
record-descriptor-accessor
make-record-field-accessor
default-record-properties
default-record-equal+  hash
default-record-custom-write
2.3.3 Record Type Bindings
record-binding?
record-id
record-binding-type
record-binding-descriptor
record-binding-predicate
record-binding-constructor
record-binding-accessor
record-binding-fields
record-binding-field-accessors
8.0

2.3 Record Types

 (require rebellion/type/record) package: rebellion

A record type is a kind of data type for composite values that contain an unordered set of named fields. The definition of each record type declares how many fields it has and what their names are. Constructing an instance of a record type requires passing a keyword argument for each field to the type’s constructor. Record types are useful when a fixed number of different pieces of data together represent a single logical thing, and there isn’t an obvious order to those pieces.

Examples:
(define-record-type opcode (name argument addressing-mode))
(define add-42
  (opcode #:name 'ADD
          #:argument 42
          #:addressing-mode 'immediate))

 

> add-42

(opcode #:addressing-mode 'immediate #:argument 42 #:name 'ADD)

> (opcode-name add-42)

'ADD

syntax

(define-record-type id (field-id ...) option ...)

 
option = #:omit-root-binding
  | #:descriptor-name descriptor-id
  | #:predicate-name predicate-id
  | #:constructor-name constructor-id
  | #:accessor-name accessor-id
  | #:pattern-name pattern-id
  | #:property-maker prop-maker-expr
  | #:inspector inspector-expr
 
  prop-maker-expr : 
(-> uninitialized-record-descriptor?
    (listof (cons/c struct-type-property? any/c)))
  inspector-expr : inspector?
Creates a new record type named id and binds the following identifiers:

Additionally, unless #:omit-root-binding is specified, the original id is bound to a record type binding for the created type. The binding behaves like pattern-id when used in match patterns and like constructor-id when used as an expression. Use #:omit-root-binding when you want control over what id is bound to, such as when creating a smart constructor.

The prop-maker-expr is used to add structure type properties to the created type, and inspector-expr is used to determine the inspector that will control the created type. See make-record-implementation for more information about these parameters.

Examples:
(define-record-type color (red green blue))
(define yellow  (color #:red 0 #:green 255 #:blue 255))

 

> yellow

(color #:blue 255 #:green 255 #:red 0)

> (color? yellow)

#t

> (color-red yellow)

0

> (color-green yellow)

255

> (color-blue yellow)

255

> (match yellow
    [(color #:red r #:blue b)
     (list r b)])

'(0 255)

syntax

(define-record-setter record-id maybe-id)

 
maybe-id = 
  | id
Creates a setter function named id for the record type bound by record-id. If id is not given, it defaults to record-id-set. The setter function accepts an instance of the record type and an optional keyword argument for each field, then returns an updated instance with each field set to the value of the corresponding keyword argument.

Examples:
(define-record-type color (red green blue))
(define-record-setter color)
(define yellow  (color #:red 0 #:green 255 #:blue 255))

 

> (color-set yellow #:red 255 #:green 0)

(color #:blue 255 #:green 0 #:red 255)

2.3.1 Record Type Information

procedure

(record-type? v)  boolean?

  v : any/c
A predicate for record types.

procedure

(record-type name 
  fields 
  [#:predicate-name predicate-name 
  #:constructor-name constructor-name 
  #:accessor-name accessor-name]) 
  record-type?
  name : symbol?
  fields : keyset?
  predicate-name : (or/c symbol? #f) = #f
  constructor-name : (or/c symbol? #f) = #f
  accessor-name : (or/c symbol? #f) = #f
Constructs a record type named name with fields as its field names. The optional predicate-name, constructor-name, and accessor-name arguments control the result of object-name on the functions implementing the type. They default to name?, constructor:name, and accessor:name respectively. This function only constructs the information representing a record type; to implement the type, use make-record-implementation.

procedure

(record-type-name type)  symbol?

  type : record-type?

procedure

(record-type-fields type)  keyset?

  type : record-type?

procedure

(record-type-predicate-name type)  (or/c symbol? #f)

  type : record-type?

procedure

(record-type-constructor-name type)  (or/c symbol? #f)

  type : record-type?

procedure

(record-type-accessor-name type)  (or/c symbol? #f)

  type : record-type?
Accessors for the various components of a record type.

2.3.2 Record Type Descriptors

Record types are implemented using structs, where the fields of the struct are always sorted by name. The type descriptor for a record type contains two functions that implement the type:

These functions can be used to dynamically construct and inspect instances of arbitrary record types at runtime, assuming the type’s descriptor is initialized. Note that the descriptor contains a single accessor function that can access any field in the record: the per-field accessors created by define-record-type are merely convenient wrappers around this accessor.

procedure

(record-descriptor? v)  boolean?

  v : any/c
A predicate for record type descriptors.

procedure

(initialized-record-descriptor? v)  boolean?

  v : any/c
A predicate for initialized record type descriptors.

procedure

(uninitialized-record-descriptor? v)  boolean?

  v : any/c
A predicate for uninitialized record type descriptors.

procedure

(make-record-implementation type 
  [#:inspector inspector 
  #:property-maker prop-maker]) 
  initialized-record-descriptor?
  type : record-type?
  inspector : inspector? = (current-inspector)
  prop-maker : 
(-> uninitialized-record-descriptor?
    (listof (cons/c struct-type-property? any/c)))
   = default-record-properties
Implements type and returns a type descriptor for the new implementation. The inspector argument behaves the same as in make-struct-type, although there are no transparent or prefab record types. The prop-maker argument is similar to the corresponding argument of make-struct-implementation. By default, record types are created with properties that make them print like transparent structures, except field names are included — see default-record-properties for details.

procedure

(record-descriptor-type descriptor)  record-type?

  descriptor : record-descriptor?
Returns the record type that descriptor implements.

procedure

(record-descriptor-predicate descriptor)  predicate/c

  descriptor : record-descriptor?
Returns a predicate that returns true when given any record instance created by descriptor. The predicate is specific to descriptor it will not return true for record instances created by any other record descriptors, even if they’re different implementations of the same record type as descriptor. This is because record types are nominal types.

procedure

(record-descriptor-constructor descriptor)  procedure?

  descriptor : record-descriptor?
Returns the record constructor of the record type implementation represented by descriptor. The constructor accepts one mandatory keyword argument for each field in the record type and returns an instance of the record type.

procedure

(record-descriptor-accessor descriptor)

  (-> (record-descriptor-predicate descriptor) natural? any/c)
  descriptor : record-descriptor?
Returns the record accessor of the record type implementation represented by descriptor. The accessor accepts two arguments: a record instance created by descriptor, and a nonnegative integer less than the number of fields in the record type. The accessor returns the value of the corresponding field in the instance. To access fields by name, first determine the integer index of the field name using the keyset returned by record-type-fields. See also make-record-field-accessor to construct a field-specific accessor function.

procedure

(make-record-field-accessor descriptor 
  field) 
  (-> (record-descriptor-predicate descriptor) any/c)
  descriptor : record-descriptor?
  field : natural?
Constructs a function that accepts an instance of the record type implemented by descriptor and returns the value of the field at position field in the record.

procedure

(default-record-properties descriptor)

  (listof (cons/c struct-type-property? any/c))
  descriptor : record-descriptor?
Returns implementations of prop:equal+hash and prop:custom-write suitable for most record types. This function is called by make-record-implementation when no prop-maker argument is supplied.

procedure

(default-record-equal+hash descriptor)  equal+hash/c

  descriptor : record-descriptor?
Builds an equality-checking function, a hashing function, and a secondary hashing function suitable for use with prop:equal+hash, each of which operate on record instances created by descriptor. Two instances are equal if and only if the fields of one instance are equal to the fields of the other. This function is used by default-record-properties to implement prop:equal+hash.

procedure

(default-record-custom-write descriptor)

  custom-write-function/c
  descriptor : record-descriptor?
Builds a custom write implementation that prints record instances created by descriptor in a manner similar to transparent Racket structs, except field values are prefixed by field names. Field names are printed as keywords, and fields are always printed in alphabetic order by name. Pretty printing is supported: the pretty printer will insert linebreaks between fields if needed, and it will keep field names and field values on the same line. This function is used by default-record-properties to implement prop:custom-write.

2.3.3 Record Type Bindings

 (require rebellion/type/record/binding)
  package: rebellion

A record type binding is a type binding for a record type. Record type bindings contain compile-time information about the record type’s name and fields, as well as runtime bindings for its predicate, type descriptor, and other runtime components. To extract a record type binding bound by define-record-type, use the record-id syntax class.

procedure

(record-binding? v)  boolean?

  v : any/c
A predicate for record type bindings.

syntax class

record-id

A syntax class for record type bindings bound by define-record-type. This class matches any identifier bound with define-syntax to a value satisfying the record-binding? predicate, similar to the static syntax class. Upon a successful match, the record-id class defines the following attributes:

Examples:
(require (for-syntax rebellion/type/record/binding))
 
(define-simple-macro (record-field-names record:record-id)
  (list record.field-name ...))
 
(define-record-type email (subject author body))

 

> (record-field-names email)

'(author body subject)

procedure

(record-binding-type binding)  record-type?

  binding : record-binding?
Returns the record type that binding is for. When a record type binding is bound with define-syntax, this can be used at compile-time to obtain information about the name and fields of the record type.

procedure

(record-binding-descriptor binding)  identifier?

  binding : record-binding?
Returns an identifier that is bound at runtime to the type descriptor for the record type bound by binding. When a record type binding is bound with define-syntax, this can be used in macro-generated code to work with record types dynamically.

procedure

(record-binding-predicate binding)  identifier?

  binding : record-binding?
Returns an identifier that is bound at runtime to the predicate for the record type bound by binding.

procedure

(record-binding-constructor binding)  identifier?

  binding : record-binding?
Returns an identifier that is bound at runtime to the record constructor for the record type bound by binding.

procedure

(record-binding-accessor binding)  identifier?

  binding : record-binding?
Returns an identifier that is bound at runtime to the record accessor for the record type bound by binding.

procedure

(record-binding-fields binding)

  (vectorof identifier? #:immutable #t)
  binding : record-binding?
Returns a vector of the identifiers used for the fields of the record type bound by binding.

procedure

(record-binding-field-accessors binding)

  (vectorof identifier? #:immutable #t)
  binding : record-binding?
Returns a vector of identifiers that are bound at runtime to the per-field accessors of the record type bound by binding.