► |  | Reference: PLT Scheme

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

▼ | 4 | Structures

4.1 | Defining Structure Types: define-struct
4.2 | Creating Structure Types
4.3 | Structure Type Properties
4.4 | Copying and Updating Structures
4.5 | Structure Utilities
4.6 | Structure Type Transformer Binding

On this page:

define-struct
struct-field-index
define-struct/ derived

Version: 4.1.4
top← prev up next →

#### 4.1`` Defining Structure Types: define-struct

Programmer-Defined Datatypes in Guide: PLT Scheme introduces define-struct.

(define-struct id-maybe-super (field ...)
struct-option ...)

id-maybe-super |  | = |  | id
|  | | |  | (id super-id)
field |  | = |  | field-id
|  | | |  | [field-id field-option ...]
struct-option |  | = |  | #:mutable
|  | | |  | #:super super-expr
|  | | |  | #:inspector inspector-expr
|  | | |  | #:auto-value auto-expr
|  | | |  | #:guard guard-expr
|  | | |  | #:property prop-expr val-exr
|  | | |  | #:transparent
|  | | |  | #:prefab
|  | | |  | #:omit-define-syntaxes
|  | | |  | #:omit-define-values
field-option |  | = |  | #:mutable
|  | | |  | #:auto

Creates a new structure type (or uses a pre-existing structure type if #:prefab is specified), and binds transformers and variables related to the structure type.

A define-struct form with n fields defines up to 4+2n names:

- struct:id, a structure type descriptor value that represents the structure type.

- make-id, a constructor procedure that takes m arguments and returns a new instance of the structure type, where m is the number of fields that do not include an #:auto option.

- id?, a predicate procedure that returns #t for instances of the structure type (constructed by make-id or the constructor for a subtype) and #f for any other value.

- id-field-id, for each field; an accessor procedure that takes an instance of the structure type and extracts the value for the corresponding field.

- set-id-field-id!, for each field that includes a #:mutable option, or when the #:mutable option is specified as a struct-option; a mutator procedure that takes an instance of the structure type and a new field value. The structure is destructively updated with the new value, and #<void> is returned.

- id, a transformer binding that encapsulates information about the structure type declaration. This binding is used to define subtypes, and it also works with the shared and match forms. For detailed information about the binding of id, see Structure Type Transformer Binding.

If super-id is provided, it must have a transformer binding of the same sort bound to id (see Structure Type Transformer Binding), and it specifies a supertype for the structure type. Alternately, the #:super option can be used to specify an expression that must produce a structure type descriptor. See Structures for more information on structure subtypes and supertypes. If both super-id and #:super are provided, a syntax error is reported.

If the #:mutable option is specified for an individual field, then the field can be mutated in instances of the structure type, and a mutator procedure is bound. Supplying #:mutable as a struct-option is the same as supplying it for all fields. If #:mutable is specified as both a field-option and struct-option, a syntax error is reported.

The #:inspector, #:auto-value, and #:guard options specify an inspector, value for automatic fields, and guard procedure, respectively. See make-struct-type for more information on these attributes of a structure type. The #:property option, which is the only one that can be supplied multiple times, attaches a property value to the structure type; see Structure Type Properties for more information on properties. The #:transparent option is a shorthand for #:inspector #f.

Use the prop:procedure to property implement an applicable structure, use prop:evt to create a structure type whose instances are synchronizable events, and so on. By convention, property names start with prop:.

The #:prefab option obtains a prefab (pre-defined, globally shared) structure type, as opposed to creating a new structure type. Such a structure type is inherently transparent and cannot have a guard or properties, so using #:prefab with #:transparent, #:inspector, #:guard, or #:property is a syntax error. If a supertype is specified, it must also be a prefab structure type.

If the #:omit-define-syntaxes option is supplied, then id is not bound as a transformer. If the #:omit-define-values option is supplied, then none of the usual variables are bound. If both are supplied, then the define-struct form is equivalent to (begin).

If #:auto is supplied as a field-option, then the constructor procedure for the structure type does not accept an argument corresponding to the field. Instead, the structure type’s automatic value is used for the field, as specified by the #:auto-value option, or as defaults to #f when #:auto-value is not supplied. The field is mutable (e.g., through reflective operations), but a mutator procedure is bound only if #:mutable is specified.

If a field includes the #:auto option, then all fields after it must also include #:auto, otherwise a syntax error is reported. If any field-option or struct-option keyword is repeated, other than #:property, a syntax error is reported.

For serialization, see define-serializable-struct.

Examples:

(define-struct posn (x y [z #:auto])
#:auto-value 0
#:transparent)

> (make-posn 1 2)
#(struct:posn 1 2 0)
> (posn? (make-posn 1 2))
#t
> (posn-y (make-posn 1 2))
2

(define-struct (color-posn posn) (hue) #:mutable)
(define cp (make-color-posn 1 2 "blue"))

> (color-posn-hue cp)
"blue"
> cp
#(struct:color-posn 1 2 0 ...)
> (set-posn-z! cp 3)
reference to undefined identifier: set-posn-z!

(struct-field-index field-id)

This form can only appear as an expression within a define-struct form; normally, it is used with #:property, especially for a property like prop:procedure. The result of a struct-field-index expression is an exact, non-negative integer that corresponds to the position within the structure declaration of the field named by field-id.

Examples:

(define-struct mood-procedure (base rating)
#:property prop:procedure (struct-field-index base))

(define happy+ (make-mood-procedure add1 10))

> (happy+ 2)
3
> (mood-procedure-rating happy+)
10

(define-struct/derived (id . rest-form)
id-maybe-super (field ...) struct-option ...)

Like define-struct, but intended for use by macros that expand to define-struct. The form immediately after define-struct/derived is used for all syntax-error reporting, and the only constraint on the form is that it starts with some id.

Examples:

> (define-syntax (define-xy-struct stx)
(syntax-case stx ()
[(ds name . rest)
(with-syntax ([orig stx])
#'(define-struct/derived orig name (x y) . rest))]))

> (define-xy-struct posn)
> (posn-x (make-posn 1 2))
1
> (define-xy-struct posn #:mutable)
> (set-posn-x! (make-posn 1 2) 0)
> (define-xy-struct posn #:bad-option)
eval:20:0: define-xy-struct: unrecognized
struct-specification keyword at: #:bad-option in:
(define-xy-struct posn #:bad-option)

top← prev up next →