On this page:
define-tuple-type
2.2.1 Tuple Type Information
tuple-type?
tuple-type
tuple-type-name
tuple-type-fields
tuple-type-predicate-name
tuple-type-constructor-name
tuple-type-accessor-name
tuple-type-size
2.2.2 Tuple Type Descriptors
tuple-descriptor?
initialized-tuple-descriptor?
uninitialized-tuple-descriptor?
make-tuple-implementation
tuple-descriptor-type
tuple-descriptor-predicate
tuple-descriptor-constructor
tuple-descriptor-accessor
make-tuple-field-accessor
default-tuple-properties
default-tuple-equal+  hash
default-tuple-custom-write
2.2.3 Tuple Type Bindings
tuple-binding?
tuple-id
tuple-binding-type
tuple-binding-descriptor
tuple-binding-predicate
tuple-binding-constructor
tuple-binding-accessor
tuple-binding-fields
tuple-binding-field-accessors
2.2.4 Tuple Chaperones and Impersonators
tuple-impersonate
8.0

2.2 Tuple Types

 (require rebellion/type/tuple) package: rebellion

A tuple type is a kind of data type for composite values that contain an ordered list of fields. The definition of each tuple type declares how many fields it has and what their names are, although those names are only observable at compile time. Constructing an instance of a tuple type requires passing a positional argument for each field to the type’s constructor. Tuple types are useful when a fixed number of different pieces of data together represent a single logical thing, and there is an obvious order to those pieces.

Examples:
(define-tuple-type point (x y))
 
(define/contract (point-distance start end)
  (-> point? point? real?)
  (match-define (point x1 y1) start)
  (match-define (point x2 y2) end)
  (define dx (- x2 x1))
  (define dy (- y2 y1))
  (sqrt (+ (sqr dx) (sqr dy))))

 

> (point-distance (point 0 0) (point 3 4))

5

> (point-distance (point 0 0) (list 3 4))

point-distance: contract violation

  expected: point?

  given: '(3 4)

  in: the 2nd argument of

      (-> point? point? real?)

  contract from: (function point-distance)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:3.0

syntax

(define-tuple-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-tuple-descriptor?
    (listof (cons/c struct-type-property? any/c)))
  inspector-expr : inspector?
Creates a new tuple type named id and binds the following identifiers:

Additionally, unless #:omit-root-binding is specified, the original id is bound to a tuple 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-tuple-implementation for more information about these parameters.

Examples:
> (define-tuple-type point (x y))
> (point 1 2)

(point 1 2)

> (point? (point 1 2))

#t

> (point-x (point 42 0))

42

> (point-y (point 42 0))

0

> (match-define (point (? positive? x) (? negative? y)) (point 3 -3))

2.2.1 Tuple Type Information

procedure

(tuple-type? v)  boolean?

  v : any/c
A predicate for tuple types.

procedure

(tuple-type name    
  fields    
  [#:predicate-name predicate-name    
  #:constructor-name constructor-name    
  #:accessor-name accessor-name])  tuple-type?
  name : interned-symbol?
  fields : (sequence/c interned-symbol?)
  predicate-name : (or/c interned-symbol? #f) = #f
  constructor-name : (or/c interned-symbol? #f) = #f
  accessor-name : (or/c interned-symbol? #f) = #f
Constructs a tuple type named name and with fields named fields. The optional predicate-name, constructor-name, and accessor-name arguments control the result of object-name on the functions implementing the type. If not provided, predicate-name defaults to name?, constructor-name defaults to constructor:name, and accessor-name defaults to accessor:name. Two tuple types constructed with the same arguments are equal?. To make an implementation of a tuple type, see make-tuple-implementation.

procedure

(tuple-type-name type)  interned-symbol?

  type : tuple-type?

procedure

(tuple-type-fields type)

  (vectorof interned-symbol? #:immutable #t)
  type : tuple-type?

procedure

(tuple-type-predicate-name type)  interned-symbol?

  type : tuple-type?

procedure

(tuple-type-constructor-name type)  interned-symbol?

  type : tuple-type?

procedure

(tuple-type-accessor-name type)  interned-symbol?

  type : tuple-type?
Accessors for the various fields of a tuple type.

procedure

(tuple-type-size type)  natural?

  type : tuple-type?
Returns the number of fields in type.

2.2.2 Tuple Type Descriptors

The type descriptor for a tuple type contains two functions that implement the type:

These functions can be used to dynamically construct and inspect instances of arbitrary tuple 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 tuple: the per-field accessors created by define-tuple-type are merely convenient wrappers around this accessor.

procedure

(tuple-descriptor? v)  boolean?

  v : any/c
A predicate for type descriptors of tuple types.

procedure

(initialized-tuple-descriptor? v)  boolean?

  v : any/c

procedure

(uninitialized-tuple-descriptor? v)  boolean?

  v : any/c
Predicates for tuple type descriptors that either have or haven’t been initialized yet. The predicate, constructor, and accessor of an uninitialized tuple descriptor must not be called until initialization is complete, as the implementations of those functions won’t exist until then. Initialization of a descriptor completes when make-tuple-implementation returns.

procedure

(make-tuple-implementation type 
  [#:guard guard 
  #:inspector inspector 
  #:property-maker prop-maker]) 
  initialized-tuple-descriptor?
  type : tuple-type?
  guard : (or/c procedure? #f) = #f
  inspector : inspector? = (current-inspector)
  prop-maker : 
(-> uninitialized-tuple-descriptor?
    (listof (cons/c struct-type-property? any/c)))
   = default-tuple-properties
Implements type and returns a type descriptor for the new implementation. The guard and inspector arguments behave the same as the corresponding arguments of make-struct-type, although there are no transparent or prefab tuple types. The prop-maker argument is similar to the corresponding argument of make-struct-implementation. By default, tuple types are created with properties that make them print and compare in a manner similar to transparent structure types — see default-tuple-properties for details.

Examples:
> (define point-descriptor
    (make-tuple-implementation (tuple-type 'point (list 'x 'y))))
> (define point (tuple-descriptor-constructor point-descriptor))
> (define point-x (make-tuple-field-accessor point-descriptor 0))
> (define point-y (make-tuple-field-accessor point-descriptor 1))
> (point 42 888)

(point 42 888)

> (point-x (point 42 888))

42

> (point-y (point 42 888))

888

procedure

(tuple-descriptor-type descriptor)  tuple-type?

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

procedure

(tuple-descriptor-predicate descriptor)  (-> any/c boolean?)

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

procedure

(tuple-descriptor-constructor descriptor)  procedure?

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

procedure

(tuple-descriptor-accessor descriptor)

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

procedure

(make-tuple-field-accessor descriptor pos)

  (-> (tuple-descriptor-predicate descriptor) any/c)
  descriptor : tuple-descriptor?
  pos : natural?
Builds a field accessor function that returns the pos field of instances of the tuple type implemented by descriptor. See make-tuple-implementation for usage examples.

procedure

(default-tuple-properties descriptor)

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

procedure

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

  descriptor : tuple-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 instances of descriptor. All fields in descriptor are compared and hashed by the returned procedures. This causes equal? to behave roughly the same as it does on transparent structure types. This function is used by default-tuple-properties to implement prop:equal+hash.

Examples:
> (define-tuple-type point (x y)
    #:property-maker
    (λ (descriptor)
      (list (cons prop:equal+hash (default-tuple-equal+hash descriptor)))))
> (equal? (point 1 2) (point 1 2))

#t

> (equal? (point 1 2) (point 2 1))

#f

procedure

(default-tuple-custom-write descriptor)

  custom-write-function/c
  descriptor : tuple-descriptor?
Constructs a custom write implementation that prints instances of the tuple type described by descriptor in a manner similar to the way that make-constructor-style-printer prints values. This function is used by default-tuple-properties to implement prop:custom-write.

Examples:
> (define-tuple-type point (x y)
    #:property-maker
    (λ (descriptor)
      (define custom-write (default-tuple-custom-write descriptor))
      (list (cons prop:custom-write custom-write))))
> (point 1 2)

(point 1 2)

> (parameterize ([pretty-print-columns 10])
    (pretty-print (point 100000000000000 200000000000000)))

(point

 100000000000000

 200000000000000)

2.2.3 Tuple Type Bindings

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

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

procedure

(tuple-binding? v)  boolean?

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

syntax class

tuple-id

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

  • binding an attribute bound to the compile-time tuple-binding? value extracted from the matched identifier.

  • name a pattern variable bound to the tuple type’s name, as a quoted symbol.

  • descriptor a pattern variable bound to the tuple type’s runtime type descriptor.

  • predicate a pattern variable bound to the tuple type’s runtime type predicate.

  • constructor a pattern variable bound to the tuple type’s runtime tuple constructor.

  • accessor a pattern variable bound to the tuple type’s runtime tuple accessor.

  • field ... a pattern variable bound to the tuple’s field identifiers.

  • field-name ... a pattern variable bound to the tuple’s field names, as quoted symbols.

  • field-accessor ... a pattern variable bound to the tuple type’s per-field runtime field accessors.

Example:
(require (for-syntax rebellion/type/tuple/binding))
 
(define-simple-macro (tuple-field-names tuple:tuple-id)
  (list tuple.field-name ...))
 
(define-tuple-type point (x y z))
 
(tuple-field-names point)

'(x y z)

procedure

(tuple-binding-type binding)  tuple-type?

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

procedure

(tuple-binding-descriptor binding)  identifier?

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

procedure

(tuple-binding-predicate binding)  identifier?

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

procedure

(tuple-binding-constructor binding)  identifier?

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

procedure

(tuple-binding-accessor binding)  identifier?

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

procedure

(tuple-binding-fields binding)

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

procedure

(tuple-binding-field-accessors binding)

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

2.2.4 Tuple Chaperones and Impersonators

procedure

(tuple-impersonate instance 
  descriptor 
  [#:properties properties 
  #:chaperone? chaperone?]) 
  (tuple-descriptor-predicate descriptor)
  instance : (tuple-descriptor-predicate descriptor)
  descriptor : initialized-tuple-descriptor?
  properties : (hash/c impersonator-property? any/c #:immutable #t)
   = empty-hash
  chaperone? : boolean? = #t
Returns an impersonator of instance with each impersonator property in properties attached to it. If chaperone? is true (the default), the returned impersonator is a chaperone.