|
|
| Line 1: |
Line 1: |
| - | == define-type / define-structure usage ==
| + | #REDIRECT [[Documentation:Special_form_define-record-type]] |
| - | | + | |
| - | Here is a traduction of some of Marc's slides from an introduction to scheme course. I believe they might be usefull since define-type / define-record are very lightly documented in the official doc.
| + | |
| - | | + | |
| - | === Syntax ===
| + | |
| - | | + | |
| - | (define-type type-name <attribute or field>...)
| + | |
| - | | + | |
| - | Attribute is a keyword. An attribute may have arguments?
| + | |
| - | | + | |
| - | Field is a symbol or a list. If a list, the first element is the field name, optionally followed by getter and setter, then field attributes
| + | |
| - | | + | |
| - | The simplest form of syntax specifies only the type name and the name of each fields
| + | |
| - | *ex:
| + | |
| - | | + | |
| - | :C: '''typedef struct { int x; int y; } point2d;'''
| + | |
| - | :Gambit : '''(define-type point2d x y)'''
| + | |
| - | | + | |
| - | *Such type definition are equivalent to multiple definitions:
| + | |
| - | (define (make-point2d x y)...) ;constructor
| + | |
| - | (define (point2d? obj)... ) ;predicate
| + | |
| - | (define (point2d-x p)...) ;access to x field
| + | |
| - | (define (point2d-x-set! p x)...) ;mutation of x field
| + | |
| - | (define (point2d-y p)...) ;access to y field
| + | |
| - | (define (point2d-y-set! p y)...) ;mutation of y field
| + | |
| - | | + | |
| - | *ex:
| + | |
| - | | + | |
| - | > (define-type point2d x y)
| + | |
| - | > (define p (make-point2d 11 22))
| + | |
| - | > p
| + | |
| - | #<point2d #2 x: 11 y: 22>
| + | |
| - | > (point2d? p)
| + | |
| - | #t
| + | |
| - | > (point2d-x p)
| + | |
| - | 11
| + | |
| - | > (point2d-x-set! p 33)
| + | |
| - | > p
| + | |
| - | #<point2d #2 x: 33 y: 22>
| + | |
| - | | + | |
| - | === define-type attributes ===
| + | |
| - | | + | |
| - | *These structures also supports inheritance
| + | |
| - | *The parameter '''extender:''' ''name'' specifies the name of the definition form to use to define a subtype:
| + | |
| - | > (define-type point2d
| + | |
| - | extender: define-type-of-point2d
| + | |
| - | x
| + | |
| - | y)
| + | |
| - | > (define-type-of-point2d point3d z)
| + | |
| - | > (define p3 (make-point3d 11 22 33))
| + | |
| - | > p3
| + | |
| - | #<point3d #2 x: 11 y: 22 z: 33>
| + | |
| - | > (point2d? p3)
| + | |
| - | #t
| + | |
| - | > (point3d? p3)
| + | |
| - | #t
| + | |
| - | > (point2d-x p3)
| + | |
| - | 11
| + | |
| - | > (point3d-z p3)
| + | |
| - | 33
| + | |
| - | | + | |
| - | | + | |
| - | TODO other define-type's parameters:
| + | |
| - | *'''id:'''
| + | |
| - | *'''constructor:'''
| + | |
| - | *'''constant-constructor:'''
| + | |
| - | *'''predicate:'''
| + | |
| - | *'''implementer:'''
| + | |
| - | *'''type-exhibitor:'''
| + | |
| - | *'''prefix:'''
| + | |
| - | *'''opaque:'''
| + | |
| - | *'''macros:'''
| + | |
| - | | + | |
| - | === Field attributes ===
| + | |
| - | | + | |
| - | *Field attributes:
| + | |
| - | **'''read-write:'''
| + | |
| - | **'''read-only:''' non mutable field
| + | |
| - | **'''equality-test:'''
| + | |
| - | **'''equality-skip:''' the '''equal?''' function will ignore this field
| + | |
| - | **'''printable:'''
| + | |
| - | **'''unprintable:''' the '''write''' function will ignore it
| + | |
| - | **'''init:''' ''cst'' initial value
| + | |
| - | | + | |
| - | *ex:
| + | |
| - | > (define-type noeud
| + | |
| - | (a unprintable:)
| + | |
| - | (b read-only: init: 9)
| + | |
| - | (c equality-skip:))
| + | |
| - | > (define x (make-noeud 1 2))
| + | |
| - | > (noeud-a-set! x x)
| + | |
| - | > x
| + | |
| - | #<noeud #2 b: 9 c: 2>
| + | |
| - | > (equal? x (make-noeud x 3))
| + | |
| - | #t
| + | |
| - | > (noeud-b-set! x 999)
| + | |
| - | *** ERROR -- Unbound variable: noeud-b-set!
| + | |
| - | | + | |
| - | All field attributes except '''init:''' can be specified at define-type level and will affect all fields. A field can specify its own field attributes to override default attributes.
| + | |
| - | | + | |
| - | *ex:
| + | |
| - | > (define-type foo unprintable: a (b printable:))
| + | |
| - | > (make-foo 1 2)
| + | |
| - | #<foo #3 b: 2>
| + | |
| - | | + | |
| - | *Field may have non-conventional getter and setter names, specified after field name in that order
| + | |
| - | | + | |
| - | *ex:
| + | |
| - | > (define-type foo (a get-a) (b get-b set-b))
| + | |
| - | > (define x (make-foo 1 2))
| + | |
| - | > (get-a x)
| + | |
| - | 1
| + | |
| - | > (set-a x 2)
| + | |
| - | *** ERROR IN (console)@14.2 -- Unbound variable: set-a
| + | |
| - | > (get-b x)
| + | |
| - | 2
| + | |
| - | > (set-b x 3)
| + | |
| - | > (get-b x)
| + | |
| - | 3
| + | |