5.7 Structure Type Transformer Binding

► |  | The Racket Reference

1 | Language Model
2 | Notation for Documentation
3 | Syntactic Forms
4 | Datatypes
5 | Structures
6 | Classes and Objects
7 | Units
8 | Contracts
9 | Pattern Matching
10 | Control Flow
11 | Concurrency and Parallelism
12 | Macros
13 | Input and Output
14 | Reflection and Security
15 | Operating System
16 | Memory Management
17 | Unsafe Operations
18 | Running Racket
| Bibliography
| Index

▼ | 5 | Structures

5.1 | Defining Structure Types: struct
5.2 | Creating Structure Types
5.3 | Structure Type Properties
5.4 | Generic Interfaces
5.5 | Copying and Updating Structures
5.6 | Structure Utilities
5.7 | Structure Type Transformer Binding

On this page:

struct-info?
checked-struct-info?
make-struct-info
extract-struct-info
struct: struct-info
prop: struct-info
prop: struct-auto-info
struct-auto-info?
struct-auto-info-lists
prop: struct-field-info
struct-field-info?
struct-field-info-list

top contents ← prev up next →

#### 5.7`` Structure Type Transformer Binding🔗ℹ

The struct form binds the name of a structure type as a transformer binding that records the other identifiers bound to the structure type, the constructor procedure, the predicate procedure, and the field accessor and mutator procedures. This information can be used during the expansion of other expressions via syntax-local-value.

For example, the struct variant for subtypes uses the base type name t to find the variable struct: t containing the base type’s descriptor; it also folds the field accessor and mutator information for the base type into the information for the subtype. As another example, the match form uses a type name to find the predicates and field accessors for the structure type. The struct form in an imported signature for unit causes the unit transformer to generate information about imported structure types, so that match and subtyping struct forms work within the unit.

The expansion-time information for a structure type can be represented directly as a list of six elements (of the same sort that the encapsulated procedure must return):

- an identifier that is bound to the structure type’s descriptor, or #f if none is known;

- an identifier that is bound to the structure type’s constructor, or #f if none is known;

- an identifier that is bound to the structure type’s predicate, or #f if none is known;

- a list of identifiers bound to the field accessors of the structure type, optionally with #f as the list’s last element. A #f as the last element indicates that the structure type may have additional fields, otherwise the list is a reliable indicator of the number of fields in the structure type. Furthermore, the accessors are listed in reverse order for the corresponding constructor arguments. (The reverse order enables sharing in the lists for a subtype and its base type.)

- a list of identifiers bound to the field mutators of the structure type, or #f for each field that has no known mutator, and optionally with an extra #f as the list’s last element (if the accessor list has such a #f). The list’s order and the meaning of a final #f are the same as for the accessor identifiers, and the length of the mutator list is the same as the accessor list’s length.

- an identifier that determines a super-type for the structure type, #f if the super-type (if any) is unknown, or #t if there is no super-type. If a super-type is specified, the identifier is also bound to structure-type expansion-time information.

Instead of this direct representation, the representation can be a structure created by make-struct-info (or an instance of a subtype of struct:struct-info), which encapsulates a procedure that takes no arguments and returns a list of six elements. Alternately, the representation can be a structure whose type has the prop:struct-info structure type property. Finally, the representation can be an instance of a structure type derived from struct:struct-info or with the prop:struct-info property that also implements prop:procedure, and where the instance is further is wrapped by make-set!-transformer. In addition, the representation may implement the prop:struct-auto-info and prop:struct-field-info properties.

Use struct-info? to recognize all allowed forms of the information, and use extract-struct-info to obtain a list from any representation.

The implementor of a syntactic form can expect users of the form to know what kind of information is available about a structure type. For example, the match implementation works with structure information containing an incomplete set of accessor bindings, because the user is assumed to know what information is available in the context of the match expression. In particular, the match expression can appear in a unit form with an imported structure type, in which case the user is expected to know the set of fields that are listed in the signature for the structure type.

(require racket/struct-info) | package: base

The bindings documented in this section are provided by the racket/struct-info library, not racket/base or racket.

> procedure (struct-info? v) → boolean?
> v : any/c

Returns #t if v is either a six-element list with the correct shape for representing structure-type information, a procedure encapsulated by make-struct-info, a structure with the prop:struct-info property, or a structure type derived from struct:struct-info or with prop:struct-info and wrapped with make-set!-transformer.

> procedure (checked-struct-info? v) → boolean?
> v : any/c

Returns #t if v is a procedure encapsulated by make-struct-info and produced by struct, but only when no parent type is specified or the parent type is also specified through a transformer binding to such a value.

> procedure (make-struct-info thunk) → struct-info?
> thunk : (-> (and/c struct-info? list?))

Encapsulates a thunk that returns structure-type information in list form. Note that accessors are listed in reverse order, as mentioned in Structure Type Transformer Binding. Note that the field names are not well-defined for struct-type informations that are created with this method, so it is likely not going to work well with forms like struct-copy and struct*.

Examples:

> > (define (new-pair? x) (displayln "new pair?") (pair? x))
> > (define (new-car x) (displayln "new car") (car x))
> > (define (new-cdr x) (displayln "new cdr") (cdr x))
> > (define-syntax new-list
> (make-struct-info
> (λ () (list #f
> #'cons
> #'new-pair?
> (list #'new-cdr #'new-car)
> (list #f #f)
> #t))))
> > (match (list 1 2 3)
> [(new-list hd tl) (append tl (list hd))])
> new pair?
> new car
> new cdr
> '(2 3 1)

Examples:

> > (struct A (x y))
> > (define (new-A-x a) (displayln "A-x") (A-x a))
> > (define (new-A-y a) (displayln "A-y") (A-y a))
> > (define (new-A? a) (displayln "A?") (A? a))
> > (define-syntax A-info
> (make-struct-info
> (λ () (list #'A
> #'A
> #'new-A?
> (list #'new-A-y #'new-A-x)
> (list #f #f)
> #t))))
> > (define-match-expander B
> (syntax-rules () [(_ x ...) (A-info x ...)]))
> > (match (A 10 20)
> [(B x y) (list y x)])
> A?
> A-x
> A-y
> '(20 10)

> procedure (extract-struct-info v) → (and/c struct-info? list?)
> v : struct-info?

Extracts the list form of the structure type information represented by v.

> value struct:struct-info : struct-type?

The structure type descriptor for the structure type returned by make-struct-info. This structure type descriptor is mostly useful for creating structure subtypes. The structure type includes a guard that checks an instance’s first field in the same way as make-struct-info.

> value prop:struct-info : struct-type-property?

The structure type property for creating new structure types like struct:struct-info. The property value must be a procedure of one argument that takes an instance structure and returns structure-type information in list form.

> value prop:struct-auto-info : struct-type-property?
> procedure (struct-auto-info? v) → boolean?
> v : any/c
> procedure (struct-auto-info-lists sai)
> → (list/c (listof identifier?) (listof identifier?))
> sai : struct-auto-info?

The prop:struct-auto-info property is implemented to provide static information about which of the accessor and mutator identifiers for a structure type correspond to #:auto fields (so that they have no corresponding argument in the constructor). The property value must be a procedure that accepts an instance structure to which the property is given, and the result must be two lists of identifiers suitable as a result from struct-auto-info-lists.

The struct-auto-info? predicate recognizes values that implement the prop:struct-auto-info property.

The struct-auto-info-lists function extracts two lists of identifiers from a value that implements the prop:struct-auto-info property. The first list should be a subset of the accessor identifiers for the structure type described by sai, and the second list should be a subset of the mutator identifiers. The two subsets correspond to #:auto fields.

> value prop:struct-field-info : struct-type-property?
> procedure (struct-field-info? v) → boolean?
> v : any/c
> procedure (struct-field-info-list sfi) → (listof symbol?)
> sfi : struct-field-info?

The prop:struct-field-info property is implemented to provide static information about field names in a structure type. The property value must be a procedure that accepts an instance structure to which the property is given, and the result must be a list of symbols suitable as a result from struct-field-info-list.

The struct-field-info? predicate recognizes values that implement the prop:struct-field-info property.

The struct-field-info-list function extracts a list of symbols from a value that implements the prop:struct-field-info property. The list should contain every immediate field name (that is, not including fields from its super struct type) in the reverse order.

Examples:

> > (struct foo (x))
> > (struct bar foo (y z))
> > (define-syntax (get-bar-field-names stx)
> #`'#,(struct-field-info-list (syntax-local-value #'bar)))
> > (get-bar-field-names)
> '(z y)

Added in version 7.7.0.9 of package base.

top contents ← prev up next →