File: record.ms

package info (click to toggle)
elk 3.0-6
  • links: PTS
  • area: main
  • in suites: potato, slink
  • size: 4,068 kB
  • ctags: 3,123
  • sloc: ansic: 20,686; lisp: 5,232; makefile: 419; awk: 91; sh: 21
file content (345 lines) | stat: -rw-r--r-- 9,989 bytes parent folder | download | duplicates (11)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
.so ../util/tmac.scheme
.Ul
.TL
Reference Manual for the
.sp .5
Elk Record Extension
.AU
Oliver Laumann
.
.Ch "Introduction"
.
.PP
The record extension to Elk allows Scheme applications to define
.Ix "record data type"
record data types (similar to, although less powerful than,
Common Lisp
.Ix structures
\f2structures\fP).
.PP
A record type can be instantiated to obtain a new
.Ix record
record (a member of the given record type).
Each record is a collection of named
.Ix fields
fields that can hold arbitrary Scheme objects.
Records are first-class Scheme objects; they are members of the
\f2record\fP data type that is disjoint from all other Scheme types.
Record types are first-class objects as well; each record type is a
member of the \f2record-type\fP Scheme data type.
.PP
The record extension provides facilities to define new record types,
create
.Ix instances
instances of existing record types, define
.Ix accessor
accessor and
.Ix modifier
modifier functions to read and write the fields of records of a
given type, and
.Ix "type predicate"
type predicates for the \f2record\fP and \f2record-type\fP data types.
.PP
In addition, the extension provides
.Ix macros
macros that simplify the definition of
.Ix constructor
constructor, accessor and modifier functions for a newly defined record type.
.
.Ch "Using the Record Extension"
.
.PP
The record extension is loaded by evaluating
.Ss
(require 'record)
.Se
in the interactive toplevel or in a Scheme program.
.PP
This causes the files
.Ix record.scm
\f2record.scm\fP and
.Ix record.o
\f2record.o\fP to be loaded into the interpreter (\f2record.o\fP has to
be linked with the interpreter on platforms that do not support dynamic
loading of object files).
.PP
Loading the record extension causes the
.Ix feature
features \f2record\fP and \f2record.o\fP to be provided.
.
.Ch "Record Types"
.
.Pr make-record-type type-name fields
.LP
\f2make-record-type\fP creates a new
.Ix "record type"
record type.
\f2type-name\fP (a string or a symbol) is the name of the record type;
it is used in the printed representation of the record type and of
records belonging to the new type.
If \f2type-name\fP is a symbol, it is converted into a string first.
.Ix fields
\f2fields\fP is a list of symbols naming the fields of a record of
the new type.
An error is signaled of the list contains duplicate names.
.LP
\f2make-record-type\fP returns the new record type (an object of the
Scheme type \f2record-type\fP).
.LP
Example:
.Ss
(define time-record
  (make-record-type 'time '(hours minutes seconds)))
.Se
.
.Pr record-type? obj
.LP
This
.Ix "type predicate"
type predicate returns #t if \f2obj\fP is a \f2record-type\fP
object (i.\|e.\& the return value of a call to \f2make-record-type\fP),
#f otherwise.
.
.Pr record-type-name rt
.LP
This procedure returns the
.Ix "type name"
type name (a string) of the record type \f2rt\fP,
i.\|e.\& the \f2type-name\fP argument that was supplied to the call
to \f2make-record-type\fP that created the record type \f2rt\fP.
.
.Pr record-type-field-names rt
.LP
\f2record-type-field-names\fP returns the list of
.Ix "field names"
field names associated with the record type \f2rt\fP (a list of
symbols), i.\|e.\& the \f2fields\fP argument that was given in the call to
.Ix make-record-type
\f2make-record-type\fP that created \f2rt\fP.
.
.[[
.Pr record-constructor rt fields
.Pr record-constructor rt
.]]
.LP
\f2record-constructor\fP returns a procedure for creating
.Ix instances
instances of the record type \f2rt\fP.
.LP
The returned procedure accepts as many arguments as there are symbols
in the list \f2fields\fP; these arguments are used as the initial
values of those
.Ix fields
fields in the newly created record instance.
The values of any fields for which no
.Ix "initial value"
initial value is specified (i.\|e.
that are not present in \f2fields\fP) are undefined.
If the \f2fields\fP argument is omitted, the field names that were given
as an argument in the call to
.Ix make-record-type
\f2make-record-type\fP that created the record type \f2rt\fP are used instead.
.LP
Example:
.Ss
(define make-time
   (record-constructor time-record))
(define noon (make-time 12 0 0))
.sp .5
(define make-uninitialized-time
   (record-constructor time-record '()))
.Se
.
.Pr record-predicate rt
.LP
\f2record-predicate\fP returns a procedure for testing membership
in the record type \f2rt\fP.
The returned procedure accepts one argument and returns #t if the
argument is a member of the record type \f2rt\fP (i.\|e.\& if it
has been created by invoking a constructor returned by calling
.Ix record constructor
\f2record-constructor\fP with \f2rt\fP as an argument), #f otherwise.
.
.Pr record-accessor rt field
.LP
\f2record-accessor\fP returns a procedure for reading the value of the
.Ix field
field named by \f2field\fP of a member of the record type \f2rt\fP.
The returned procedure accepts one argument, which must be a record
of the record type \f2rt\fP; it returns the current value of the
specified field in that record.
\f2field\fP must be a member of the list of field names that was supplied
to the call to
.Ix make-record-type
\f2make-record-type\fP that created \f2rt\fP.
.LP
Example:
.Ss
(define time-hours
  (record-accessor time-record 'hours))
.sp .5
(define noon ((record-constructor time-record) 12 0 0))
(time-hours noon)  \f2\(-> 12\fP
.Se
.
.Pr record-modifier rt field
.LP
\f2record-modifier\fP returns a procedure for writing the value of the
.Ix field
field named by \f2field\fP of a member of the record type \f2rt\fP.
The returned procedure accepts two arguments: a record
of the record type \f2rt\fP and an arbitrary object; it stores the given
object into the specified field in that record and returns the
previous value of the field.
\f2field\fP must be a member of the list of field names that was supplied
to the call to
.Ix make-record-type
\f2make-record-type\fP that created \f2rt\fP.
.LP
Example
.Ss
(define set-time-hours!
  (record-modifier time-record 'hours))
.Se
.
.Pr describe-record-type rt
.LP
This procedure prints the names of the
.Ix fields
fields associated with the record type \f2rt\fP; it is automatically
invoked by the standard
.Ix describe
\f2describe\fP procedure of Elk if \f2describe\fP is invoked with a
record type.
.
.Ch "Records"
.
.Pr record? obj
.LP
This
.Ix "type predicate"
type predicate returns #t if \f2obj\fP is an object of type \f2record\fP
(i.\|e.\& the return value of a call to a record
.Ix constructor
constructor of any record type), #f otherwise.
.
.Pr record-type-descriptor record
.LP
This procedure returns the
.Ix "record type"
record type representing the type of the given record.
The returned record type object is equal (in the sense of \f2eq?\fP)
to the record type argument that was passed to
.Ix record-constructor
\f2record-constructor\fP in the call that created the constructor
procedure that created \f2record\fP.
.LP
Example: evaluating the expression
.Ss
((record-predicate (record-type-descriptor r)) r)
.Se
always yields #t for any given record \f2r\fP.
.
.Pr record-values record
.LP
\f2record-values\fP returns the current contents of the fields of
\f2record\fP as a
.Ix vector
vector.
The \f2n\fPth element of the vector corresponds to the field with the
name given as the \f2n\fPth element of the \f2fields\fP argument in
the call to
.Ix make-record-type
\f2make-record-type\fP that created the type to which \f2record\fP belongs.
.LP
The returned vector is not a copy of the actual fields; i.\|e.\& modifying
the contents of the vector directly writes the corresponding fields
of the record.
.
.Pr describe-record record
.LP
This procedure prints the names and current values of the
.Ix fields
fields of the given record; it is automatically invoked by the standard
.Ix describe
\f2describe\fP procedure of Elk if \f2describe\fP is invoked with a record.
.
.Ch "Convenience Macros"
.PP
The 
.Ix macros
macros described in this section are loaded by evaluating
.Ss
(require 'recordutil)
.Se
after having loaded the record extension.
This causes the file
.Ix recordutil.scm
\f2recordutil.scm\fP to be loaded and defines the
.Ix feature
.Ix recordutil
feature \f2recordutil\fP.
.
.Sy define-record-type name fields
.LP
This macro defines a variable \f2<name>-record\fP, invokes the procedure
.Ix make-record-type
\f2make-record-type\fP with the given \f2name\fP and
\f2fields\fP, and assigns the result to this variable.
In addition, \f2define-record-type\fP defines a
.Ix "type predicate"
type predicate for the new record type as \f2<name>\-record?\fP and a
.Ix constructor
constructor function as \f2make\-<name>\-record\fP.
The constructor function accepts no arguments and returns an
uninitialized record of the newly defined record type.
.LP
Example:
.Ss
(require 'record)
(require 'recordutil)
.sp .5
(define-record-type
  time (hours minutes seconds))
.sp .3
(record-type? time-record)  \f2\(-> #t\fP
.sp .3
(define t (make-time-record))
.sp .3
(time-record? t)  \f2\(-> #t\fP
.Se
.
.[[
.Sy define-record-accessors rt
.Sy define-record-modifiers rt
.]]
.LP
The macro \f2define-record-accessors\fP (\f2define-record-modifiers\fP)
defines
.Ix accessor
.Ix modifier
accessor (modifier) functions for the fields of the record type \f2rt\fP.
For each field named \f2field\fP, \f2define-record-accessors\fP
(\f2define-record-modifiers\fP) defines a function \f2<name>\-<field>\fP
(\f2set\-<name>\-<field>!\fP), where \f2name\fP is the type name of
the given record type.
Each of the functions is the result of a call to
.Ix record-accessor
.Ix record-modifier
\f2record-accessor\fP (\f2record-modifier\fP) as described above, with
the arguments \f2rt\fP and the name of the field.
.LP
Example:
.Ss
(define-record-type time (hours minutes seconds))
(define-record-modifiers time-record)
.sp .3
(define noon (make-time-record))
(set-time-hours! noon 12)
(set-time-minutes! noon 0)
(set-time-seconds! noon 0)
.sp .5
(define-record-accessors time-record)
.sp .3
(time-hours noon)  \f2\(-> 12\fP
.Se