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
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
|
@page
@node Utility Functions
@chapter General Utility Functions
@c FIXME::martin: Review me!
This chapter contains information about procedures which are not cleanly
tied to a specific data type. Because of their wide range of
applications, they are collected in a @dfn{utility} chapter.
@menu
* Equality:: When are two values `the same'?
* Property Lists:: Managing metainformation about Scheme objects.
* Primitive Properties:: A modern interface to object properties.
* Sorting:: Sort utility procedures.
* Copying:: Copying deep structures.
* General Conversion:: Converting objects to strings.
* Hooks:: User-customizable event lists.
@end menu
@node Equality
@section Equality
@c FIXME::martin: Review me!
@cindex sameness
@cindex equality
Three different kinds of @dfn{sameness} are defined in Scheme.
@itemize @bullet
@item
Two values can refer to exactly the same object.
@item
Two objects can have the same @dfn{value}.
@item
Two objects can be structurally equivalent.
@end itemize
The differentiation between these three kinds is important, because
determining whether two values are the same objects is very efficient,
while determining structural equivalence can be quite expensive
(consider comparing two very long lists). Therefore, three different
procedures for testing for equality are provided, which correspond to
the three kinds of @dfn{sameness} defined above.
@rnindex eq?
@deffn {Scheme Procedure} eq? x y
Return @code{#t} iff @var{x} references the same object as @var{y}.
@code{eq?} is similar to @code{eqv?} except that in some cases it is
capable of discerning distinctions finer than those detectable by
@code{eqv?}.
@end deffn
@rnindex eqv?
@deffn {Scheme Procedure} eqv? x y
The @code{eqv?} procedure defines a useful equivalence relation on objects.
Briefly, it returns @code{#t} if @var{x} and @var{y} should normally be
regarded as the same object. This relation is left slightly open to
interpretation, but works for comparing immediate integers, characters,
and inexact numbers.
@end deffn
@rnindex equal?
@deffn {Scheme Procedure} equal? x y
Return @code{#t} iff @var{x} and @var{y} are recursively @code{eqv?} equivalent.
@code{equal?} recursively compares the contents of pairs,
vectors, and strings, applying @code{eqv?} on other objects such as
numbers and symbols. A rule of thumb is that objects are generally
@code{equal?} if they print the same. @code{equal?} may fail to
terminate if its arguments are circular data structures.
@end deffn
@node Property Lists
@section Property Lists
Every object in the system can have a @dfn{property list} that may
be used for information about that object. For example, a
function may have a property list that includes information about
the source file in which it is defined.
Property lists are implemented as assq lists (@pxref{Association Lists}).
Currently, property lists are implemented differently for procedures and
closures than for other kinds of objects. Therefore, when manipulating
a property list associated with a procedure object, use the
@code{procedure} functions; otherwise, use the @code{object} functions.
@deffn {Scheme Procedure} object-properties obj
@deffnx {C Function} scm_object_properties (obj)
Return @var{obj}'s property list.
@end deffn
@deffn {Scheme Procedure} set-object-properties! obj alist
@deffnx {C Function} scm_set_object_properties_x (obj, alist)
Set @var{obj}'s property list to @var{alist}.
@end deffn
@deffn {Scheme Procedure} object-property obj key
@deffnx {C Function} scm_object_property (obj, key)
Return the property of @var{obj} with name @var{key}.
@end deffn
@deffn {Scheme Procedure} set-object-property! obj key value
@deffnx {C Function} scm_set_object_property_x (obj, key, value)
In @var{obj}'s property list, set the property named @var{key}
to @var{value}.
@end deffn
[Interface bug: there should be a second level of interface in which
the user provides a "property table" that is possibly private.]
@node Primitive Properties
@section Primitive Properties
@deffn {Scheme Procedure} primitive-make-property not_found_proc
@deffnx {C Function} scm_primitive_make_property (not_found_proc)
Create a @dfn{property token} that can be used with
@code{primitive-property-ref} and @code{primitive-property-set!}.
See @code{primitive-property-ref} for the significance of
@var{not_found_proc}.
@end deffn
@deffn {Scheme Procedure} primitive-property-ref prop obj
@deffnx {C Function} scm_primitive_property_ref (prop, obj)
Return the property @var{prop} of @var{obj}. When no value
has yet been associated with @var{prop} and @var{obj}, call
@var{not-found-proc} instead (see @code{primitive-make-property})
and use its return value. That value is also associated with
@var{obj} via @code{primitive-property-set!}. When
@var{not-found-proc} is @code{#f}, use @code{#f} as the
default value of @var{prop}.
@end deffn
@deffn {Scheme Procedure} primitive-property-set! prop obj val
@deffnx {C Function} scm_primitive_property_set_x (prop, obj, val)
Associate @var{code} with @var{prop} and @var{obj}.
@end deffn
@deffn {Scheme Procedure} primitive-property-del! prop obj
@deffnx {C Function} scm_primitive_property_del_x (prop, obj)
Remove any value associated with @var{prop} and @var{obj}.
@end deffn
@node Sorting
@section Sorting
@c FIXME::martin: Review me!
@cindex sorting
@cindex sorting lists
@cindex sorting vectors
Sorting is very important in computer programs. Therefore, Guile comes
with several sorting procedures built-in. As always, procedures with
names ending in @code{!} are side-effecting, that means that they may
modify their parameters in order to produce their results.
The first group of procedures can be used to merge two lists (which must
be already sorted on their own) and produce sorted lists containing
all elements of the input lists.
@deffn {Scheme Procedure} merge alist blist less
@deffnx {C Function} scm_merge (alist, blist, less)
Merge two already sorted lists into one.
Given two lists @var{alist} and @var{blist}, such that
@code{(sorted? alist less?)} and @code{(sorted? blist less?)},
return a new list in which the elements of @var{alist} and
@var{blist} have been stably interleaved so that
@code{(sorted? (merge alist blist less?) less?)}.
Note: this does _not_ accept vectors.
@end deffn
@deffn {Scheme Procedure} merge! alist blist less
@deffnx {C Function} scm_merge_x (alist, blist, less)
Takes two lists @var{alist} and @var{blist} such that
@code{(sorted? alist less?)} and @code{(sorted? blist less?)} and
returns a new list in which the elements of @var{alist} and
@var{blist} have been stably interleaved so that
@code{(sorted? (merge alist blist less?) less?)}.
This is the destructive variant of @code{merge}
Note: this does _not_ accept vectors.
@end deffn
The following procedures can operate on sequences which are either
vectors or list. According to the given arguments, they return sorted
vectors or lists, respectively. The first of the following procedures
determines whether a sequence is already sorted, the other sort a given
sequence. The variants with names starting with @code{stable-} are
special in that they maintain a special property of the input sequences:
If two or more elements are the same according to the comparison
predicate, they are left in the same order as they appeared in the
input.
@deffn {Scheme Procedure} sorted? items less
@deffnx {C Function} scm_sorted_p (items, less)
Return @code{#t} iff @var{items} is a list or a vector such that
for all 1 <= i <= m, the predicate @var{less} returns true when
applied to all elements i - 1 and i
@end deffn
@deffn {Scheme Procedure} sort items less
@deffnx {C Function} scm_sort (items, less)
Sort the sequence @var{items}, which may be a list or a
vector. @var{less} is used for comparing the sequence
elements. This is not a stable sort.
@end deffn
@deffn {Scheme Procedure} sort! items less
@deffnx {C Function} scm_sort_x (items, less)
Sort the sequence @var{items}, which may be a list or a
vector. @var{less} is used for comparing the sequence
elements. The sorting is destructive, that means that the
input sequence is modified to produce the sorted result.
This is not a stable sort.
@end deffn
@deffn {Scheme Procedure} stable-sort items less
@deffnx {C Function} scm_stable_sort (items, less)
Sort the sequence @var{items}, which may be a list or a
vector. @var{less} is used for comparing the sequence elements.
This is a stable sort.
@end deffn
@deffn {Scheme Procedure} stable-sort! items less
@deffnx {C Function} scm_stable_sort_x (items, less)
Sort the sequence @var{items}, which may be a list or a
vector. @var{less} is used for comparing the sequence elements.
The sorting is destructive, that means that the input sequence
is modified to produce the sorted result.
This is a stable sort.
@end deffn
The procedures in the last group only accept lists or vectors as input,
as their names indicate.
@deffn {Scheme Procedure} sort-list items less
@deffnx {C Function} scm_sort_list (items, less)
Sort the list @var{items}, using @var{less} for comparing the
list elements. This is a stable sort.
@end deffn
@deffn {Scheme Procedure} sort-list! items less
@deffnx {C Function} scm_sort_list_x (items, less)
Sort the list @var{items}, using @var{less} for comparing the
list elements. The sorting is destructive, that means that the
input list is modified to produce the sorted result.
This is a stable sort.
@end deffn
@deffn {Scheme Procedure} restricted-vector-sort! vec less startpos endpos
@deffnx {C Function} scm_restricted_vector_sort_x (vec, less, startpos, endpos)
Sort the vector @var{vec}, using @var{less} for comparing
the vector elements. @var{startpos} and @var{endpos} delimit
the range of the vector which gets sorted. The return value
is not specified.
@end deffn
@node Copying
@section Copying Deep Structures
@c FIXME::martin: Review me!
The procedures for copying lists (@pxref{Lists}) only produce a flat
copy of the input list, and currently Guile does not even contain
procedures for copying vectors. @code{copy-tree} can be used for these
application, as it does not only copy the spine of a list, but also
copies any pairs in the cars of the input lists.
@deffn {Scheme Procedure} copy-tree obj
@deffnx {C Function} scm_copy_tree (obj)
Recursively copy the data tree that is bound to @var{obj}, and return a
pointer to the new data structure. @code{copy-tree} recurses down the
contents of both pairs and vectors (since both cons cells and vector
cells may point to arbitrary objects), and stops recursing when it hits
any other object.
@end deffn
@node General Conversion
@section General String Conversion
@c FIXME::martin: Review me!
When debugging Scheme programs, but also for providing a human-friendly
interface, a procedure for converting any Scheme object into string
format is very useful. Conversion from/to strings can of course be done
with specialized procedures when the data type of the object to convert
is known, but with this procedure, it is often more comfortable.
@code{object->string} converts an object by using a print procedure for
writing to a string port, and then returning the resulting string.
Converting an object back from the string is only possible if the object
type has a read syntax and the read syntax is preserved by the printing
procedure.
@deffn {Scheme Procedure} object->string obj [printer]
@deffnx {C Function} scm_object_to_string (obj, printer)
Return a Scheme string obtained by printing @var{obj}.
Printing function can be specified by the optional second
argument @var{printer} (default: @code{write}).
@end deffn
@node Hooks
@section Hooks
@tpindex Hooks
@c FIXME::martin: Review me!
A hook is basically a list of procedures to be called at well defined
points in time. Hooks are used internally for several debugging
facilities, but they can be used in user code, too.
Hooks are created with @code{make-hook}, then procedures can be added to
a hook with @code{add-hook!} or removed with @code{remove-hook!} or
@code{reset-hook!}. The procedures stored in a hook can be invoked with
@code{run-hook}.
@menu
* Hook Examples:: Hook usage by example.
* Hook Reference:: Reference of all hook procedures.
@end menu
@node Hook Examples
@subsection Hook Examples
Hook usage is shown by some examples in this section. First, we will
define a hook of arity 2 --- that is, the procedures stored in the hook
will have to accept two arguments.
@lisp
(define hook (make-hook 2))
hook
@result{} #<hook 2 40286c90>
@end lisp
Now we are ready to add some procedures to the newly created hook with
@code{add-hook!}. In the following example, two procedures are added,
which print different messages and do different things with their
arguments. When the procedures have been added, we can invoke them
using @code{run-hook}.
@lisp
(add-hook! hook (lambda (x y)
(display "Foo: ")
(display (+ x y))
(newline)))
(add-hook! hook (lambda (x y)
(display "Bar: ")
(display (* x y))
(newline)))
(run-hook hook 3 4)
@print{} Bar: 12
@print{} Foo: 7
@end lisp
Note that the procedures are called in reverse order than they were
added. This can be changed by providing the optional third argument
on the second call to @code{add-hook!}.
@lisp
(add-hook! hook (lambda (x y)
(display "Foo: ")
(display (+ x y))
(newline)))
(add-hook! hook (lambda (x y)
(display "Bar: ")
(display (* x y))
(newline))
#t) ; @r{<- Change here!}
(run-hook hook 3 4)
@print{} Foo: 7
@print{} Bar: 12
@end lisp
@node Hook Reference
@subsection Hook Reference
When a hook is created with @code{make-hook}, you can supply the arity
of the procedures which can be added to the hook. The arity defaults to
zero. All procedures of a hook must have the same arity, and when the
procedures are invoked using @code{run-hook}, the number of arguments
must match the arity of the procedures.
The order in which procedures are added to a hook matters. If the third
parameter to @var{add-hook!} is omitted or is equal to @code{#f}, the
procedure is added in front of the procedures which might already be on
that hook, otherwise the procedure is added at the end. The procedures
are always called from first to last when they are invoked via
@code{run-hook}.
When calling @code{hook->list}, the procedures in the resulting list are
in the same order as they would have been called by @code{run-hook}.
@deffn {Scheme Procedure} make-hook [n_args]
@deffnx {C Function} scm_make_hook (n_args)
Create a hook for storing procedure of arity @var{n_args}.
@var{n_args} defaults to zero. The returned value is a hook
object to be used with the other hook procedures.
@end deffn
@deffn {Scheme Procedure} hook? x
@deffnx {C Function} scm_hook_p (x)
Return @code{#t} if @var{x} is a hook, @code{#f} otherwise.
@end deffn
@deffn {Scheme Procedure} hook-empty? hook
@deffnx {C Function} scm_hook_empty_p (hook)
Return @code{#t} if @var{hook} is an empty hook, @code{#f}
otherwise.
@end deffn
@deffn {Scheme Procedure} add-hook! hook proc [append_p]
@deffnx {C Function} scm_add_hook_x (hook, proc, append_p)
Add the procedure @var{proc} to the hook @var{hook}. The
procedure is added to the end if @var{append_p} is true,
otherwise it is added to the front. The return value of this
procedure is not specified.
@end deffn
@deffn {Scheme Procedure} remove-hook! hook proc
@deffnx {C Function} scm_remove_hook_x (hook, proc)
Remove the procedure @var{proc} from the hook @var{hook}. The
return value of this procedure is not specified.
@end deffn
@deffn {Scheme Procedure} reset-hook! hook
@deffnx {C Function} scm_reset_hook_x (hook)
Remove all procedures from the hook @var{hook}. The return
value of this procedure is not specified.
@end deffn
@deffn {Scheme Procedure} run-hook hook . args
@deffnx {C Function} scm_run_hook (hook, args)
Apply all procedures from the hook @var{hook} to the arguments
@var{args}. The order of the procedure application is first to
last. The return value of this procedure is not specified.
@end deffn
@deffn {Scheme Procedure} hook->list hook
@deffnx {C Function} scm_hook_to_list (hook)
Convert the procedure list of @var{hook} to a list.
@end deffn
@c Local Variables:
@c TeX-master: "guile.texi"
@c End:
|