sigildocs

(sigil struct)

(sigil struct) - Struct Types

Provides define-struct for creating named-field data structures with:

  • Keyword-based construction
  • Optional field defaults
  • Optional per-field mutability
  • Optional field type annotations for procedure specs
  • Struct embedding via include:

Basic Usage

(import (sigil struct))

(define-struct person
  (name default: "")
  (age default: 0))

;; Constructor uses type name with keywords:
(define alice (person name: "Alice" age: 30))

;; Accessors use typename-fieldname:
(person-name alice)  ; => "Alice"
(person-age alice)   ; => 30

;; Predicate:
(person? alice)      ; => #t

Mutable Fields

Fields are immutable by default. Use mutable: #t for mutability:

(define-struct counter
  (value default: 0 mutable: #t))

(define c (counter))
(set-counter-value! c 10)
(counter-value c)  ; => 10

Copy-Construction

Pass an existing struct as the first argument to copy with modifications:

(define alice (person name: "Alice" age: 30))
(define bob (person alice name: "Bob"))
;; bob has name: "Bob", age: 30

Field Type Annotations

Fields can have type predicates for automatic procedure spec generation:

(define-struct point
  (x number?)
  (y number?))

(procedure-spec point-x)  ; => (point? -> number?)
(procedure-spec point)    ; => ((x: number?) (y: number?) -> point?)

Type predicates go after the field name, before keyword options:

(define-struct counter
  (value number? default: 0 mutable: #t))

Struct Embedding

Use include: to embed another struct's fields:

(define-struct employee
  include: person
  (department default: "Engineering")
  (salary))

(define emp (employee name: "Alice" age: 30 department: "Eng" salary: 80000))
(employee-name emp)       ; => "Alice" (inherited field)
(employee-department emp) ; => "Eng" (own field)
(employee->person emp)    ; => #<person name: "Alice" age: 30>

Exports

struct?procedure

Test if a value is a struct instance.

(struct? (person name: "Alice"))  ; => #t
(struct? '(1 2 3))               ; => #f
struct-type?procedure

Test if a value is a struct type descriptor.

(struct-type? (struct-type-of my-struct))  ; => #t

Get the struct type descriptor from a struct instance.

(struct-type-of (person name: "Alice"))
; => #<struct-type person>

Get the name of a struct type as a symbol.

(struct-type-name (struct-type-of p))  ; => person

Get the number of fields in a struct type (including inherited).

(struct-type-field-count (struct-type-of p))  ; => 2

Get the field names of a struct type as an array.

(struct-type-field-names (struct-type-of p))  ; => #(name age)

Get the parent struct type, or #f if none.

(struct-type-parent (struct-type-of emp))
; => #<struct-type person>

Get the field index for a given field name in a struct type.

Returns the zero-based index, or #f if the field doesn't exist.

(struct-field-index (struct-type-of p) 'name)  ; => 0
(struct-field-index (struct-type-of p) 'age)   ; => 1

Tracks struct type metadata during compilation so that child structs can generate inherited accessors. The registry: maps type-name symbol to (field-names parent-type) Uses a mutable list so it persists across macro expansions

Register a struct type's metadata field-types is a list of type predicates (symbols or #f) parallel to field-names

Collect all fields from a struct-type object by walking parent chain

Try to look up a struct type from imported modules Looks up the constructor and extracts the type from its metadata. Returns (all-field-names #f all-field-types) or #f if not found Note: Returns #f for parent since we've already collected all fields

Collect field types from constructor metadata Returns a list of type predicates (symbols or #f) for all fields

Look up a struct type's metadata First checks local registry, then falls back to imported types Returns (field-names parent-type field-types) or #f if not found

Get all field names from a type (own + inherited). Walks the parent chain via procedure metadata.

Get all field types from a type (own + inherited). Walks the parent chain, parallel to %get-inherited-fields.

%no-defaultvariable

Sentinel for "no default provided" (required field)

Helper: Unwrap syntax object to get datum

Helper: Get docstring from syntax object

Helper: Get srcloc from syntax object

Helper: Process field spec into (name default mutable? docstring type-pred)

type-pred is a symbol like number? or #f if no type annotation. Type predicates appear after the field name and before keyword options: (x number? default: 0 mutable: #t)

make-accessorprocedure

Helper: Build accessor definition with docstring

make-mutatorprocedure

Helper: Build mutator definition with auto-generated docstring

The define-struct macro transformer

Define a struct type with named fields.

Creates a constructor, predicate, and field accessors for a new struct type. Fields can have defaults (default:), be mutable (mutable: #t), and structs can embed other structs (include:).

(define-struct person
  (name default: "")
  (age default: 0 mutable: #t))

(define p (person name: "Alice" age: 30))
(person-name p)       ; => "Alice"
(set-person-age! p 31)