1 | [[tags: egg]] |
---|
2 | |
---|
3 | == defstruct |
---|
4 | |
---|
5 | [[toc:]] |
---|
6 | |
---|
7 | === Description |
---|
8 | |
---|
9 | A more convenient form of {{define-record}} |
---|
10 | |
---|
11 | === Author |
---|
12 | |
---|
13 | Dorai Sitaram, ported to CHICKEN by [[/users/felix winkelmann|felix winkelmann]], with improvements by [[/users/peter-bex|Peter Bex]] |
---|
14 | |
---|
15 | === Requirements |
---|
16 | |
---|
17 | This only needs the [[srfi-1]] egg. |
---|
18 | |
---|
19 | === Documentation |
---|
20 | |
---|
21 | <macro>(defstruct NAME SLOT ...)</macro> |
---|
22 | |
---|
23 | Defines a record type with the name {{NAME}}. {{SLOT}} may be a symbol |
---|
24 | or a list of the form {{(NAME INIT)}} where {{INIT}} is the default |
---|
25 | value of the slot (the {{INIT}} expression will only be evaluated when |
---|
26 | no value is given in the constructor procedure. It defaults to {{#f}} |
---|
27 | when none is provided). |
---|
28 | |
---|
29 | The {{defstruct}} macro expands into predicate and accessor functions |
---|
30 | (just like the native {{define-record}}): |
---|
31 | |
---|
32 | <enscript highlight="scheme"> |
---|
33 | (import defstruct) |
---|
34 | |
---|
35 | (defstruct point x y) |
---|
36 | |
---|
37 | ;; Creates code equivalent to the following: |
---|
38 | (begin |
---|
39 | (define (point? x) ...) ; is x a point? |
---|
40 | (define (point-x p) ...) ; return x slot of point p |
---|
41 | (define (point-x-set! p n) ...) ; change x slot of point p to n |
---|
42 | ...) |
---|
43 | </enscript> |
---|
44 | |
---|
45 | Additionally, a constructor procedure {{make-STRUCTNAME}} is defined, |
---|
46 | which accepts initialization values for all slots specified as keyword |
---|
47 | arguments: |
---|
48 | |
---|
49 | <enscript highlight="scheme"> |
---|
50 | (define p1 (make-point x: 99 y: 42)) |
---|
51 | => ; a point with x = 99 and y = 42 |
---|
52 | </enscript> |
---|
53 | |
---|
54 | If keywords for some slots are missing, their initialization values |
---|
55 | default to those supplied in the {{defstruct}} call, or else {{#f}}. |
---|
56 | |
---|
57 | There are also two procedures {{update-STRUCTNAME}} and |
---|
58 | {{set-STRUCTNAME!}} defined for functionally and destructively |
---|
59 | updating selected values in an existing record: |
---|
60 | |
---|
61 | <enscript highlight="scheme"> |
---|
62 | (define p2 (update-point p1 x: 100)) |
---|
63 | p2 |
---|
64 | => ; a point with x = 100 and y = 42 |
---|
65 | |
---|
66 | (= p1-x 99) |
---|
67 | => #t |
---|
68 | |
---|
69 | (set-point! p1 x: 100) |
---|
70 | (= p1-x 100) |
---|
71 | => #t |
---|
72 | </enscript> |
---|
73 | |
---|
74 | Finally, there are two conversion procedures for converting to and |
---|
75 | from alists, {{STRUCTNAME->alist}} and {{alist->STRUCTNAME}}: |
---|
76 | |
---|
77 | <enscript highlight="scheme"> |
---|
78 | (define p3 (alist->point '((x . 1) (y . 2)))) |
---|
79 | p3 |
---|
80 | => ; a point with x = 1 and y = 2 |
---|
81 | |
---|
82 | (define p4 (make-point x: 123 y: 456)) |
---|
83 | (point->alist p4) |
---|
84 | => ((x . 123) (y . 456)) |
---|
85 | </enscript> |
---|
86 | |
---|
87 | === Bugs and limitations |
---|
88 | |
---|
89 | This macro is unhygienic which, while resulting in concise syntax, has |
---|
90 | some drawbacks: |
---|
91 | |
---|
92 | * Just like with {{define-record}} you cannot use field names ending with {{-set!}} if you also have a similar field name not ending with {{-set!}}. |
---|
93 | * Just like with {{define-record}} you should avoid defining record types with a name that is a prefix of another record type's name in the same module, because that might cause naming clashes. |
---|
94 | * For the same reason, you should avoid defining record types named {{make}} or {{update}}. |
---|
95 | * You cannot use a field named {{>alist}}. |
---|
96 | |
---|
97 | === License |
---|
98 | |
---|
99 | Copyright (c) 2005, Dorai Sitaram |
---|
100 | Copyright (c) 2005, Felix Winkelmann (Chicken port) |
---|
101 | Copyright (c) 2008-2018, Peter Bex (Hygienic Chicken port + extensions) |
---|
102 | All rights reserved. |
---|
103 | |
---|
104 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following |
---|
105 | conditions are met: |
---|
106 | |
---|
107 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following |
---|
108 | disclaimer. |
---|
109 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following |
---|
110 | disclaimer in the documentation and/or other materials provided with the distribution. |
---|
111 | Neither the name of the author nor the names of its contributors may be used to endorse or promote |
---|
112 | products derived from this software without specific prior written permission. |
---|
113 | |
---|
114 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS |
---|
115 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY |
---|
116 | AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR |
---|
117 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
---|
118 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
---|
119 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
---|
120 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
---|
121 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
---|
122 | POSSIBILITY OF SUCH DAMAGE. |
---|