Commit | Line | Data |
---|---|---|
a0e07ba4 NJ |
1 | @page |
2 | @node Utility Functions | |
3 | @chapter General Utility Functions | |
4 | ||
5 | @c FIXME::martin: Review me! | |
6 | ||
7 | This chapter contains information about procedures which are not cleanly | |
8 | tied to a specific data type. Because of their wide range of | |
4c731ece | 9 | applications, they are collected in a @dfn{utility} chapter. |
a0e07ba4 NJ |
10 | |
11 | @menu | |
12 | * Equality:: When are two values `the same'? | |
85a9b4ed | 13 | * Property Lists:: Managing meta-information about Scheme objects. |
4c731ece | 14 | * Primitive Properties:: A modern interface to object properties. |
a0e07ba4 NJ |
15 | * Sorting:: Sort utility procedures. |
16 | * Copying:: Copying deep structures. | |
17 | * General Conversion:: Converting objects to strings. | |
4c731ece | 18 | * Hooks:: User-customizable event lists. |
a0e07ba4 NJ |
19 | @end menu |
20 | ||
21 | ||
22 | @node Equality | |
23 | @section Equality | |
24 | ||
25 | @c FIXME::martin: Review me! | |
26 | ||
27 | @cindex sameness | |
28 | @cindex equality | |
29 | ||
30 | Three different kinds of @dfn{sameness} are defined in Scheme. | |
31 | ||
32 | @itemize @bullet | |
33 | @item | |
34 | Two values can refer to exactly the same object. | |
35 | ||
36 | @item | |
37 | Two objects can have the same @dfn{value}. | |
38 | ||
39 | @item | |
40 | Two objects can be structurally equivalent. | |
41 | @end itemize | |
42 | ||
43 | The differentiation between these three kinds is important, because | |
44 | determining whether two values are the same objects is very efficient, | |
45 | while determining structural equivalence can be quite expensive | |
46 | (consider comparing two very long lists). Therefore, three different | |
47 | procedures for testing for equality are provided, which correspond to | |
48 | the three kinds of @dfn{sameness} defined above. | |
49 | ||
50 | @rnindex eq? | |
8f85c0c6 | 51 | @deffn {Scheme Procedure} eq? x y |
a0e07ba4 NJ |
52 | Return @code{#t} iff @var{x} references the same object as @var{y}. |
53 | @code{eq?} is similar to @code{eqv?} except that in some cases it is | |
54 | capable of discerning distinctions finer than those detectable by | |
55 | @code{eqv?}. | |
56 | @end deffn | |
57 | ||
58 | @rnindex eqv? | |
8f85c0c6 | 59 | @deffn {Scheme Procedure} eqv? x y |
a0e07ba4 NJ |
60 | The @code{eqv?} procedure defines a useful equivalence relation on objects. |
61 | Briefly, it returns @code{#t} if @var{x} and @var{y} should normally be | |
62 | regarded as the same object. This relation is left slightly open to | |
63 | interpretation, but works for comparing immediate integers, characters, | |
64 | and inexact numbers. | |
65 | @end deffn | |
66 | ||
67 | @rnindex equal? | |
8f85c0c6 | 68 | @deffn {Scheme Procedure} equal? x y |
a0e07ba4 NJ |
69 | Return @code{#t} iff @var{x} and @var{y} are recursively @code{eqv?} equivalent. |
70 | @code{equal?} recursively compares the contents of pairs, | |
71 | vectors, and strings, applying @code{eqv?} on other objects such as | |
72 | numbers and symbols. A rule of thumb is that objects are generally | |
73 | @code{equal?} if they print the same. @code{equal?} may fail to | |
74 | terminate if its arguments are circular data structures. | |
75 | @end deffn | |
76 | ||
77 | ||
78 | @node Property Lists | |
79 | @section Property Lists | |
80 | ||
81 | Every object in the system can have a @dfn{property list} that may | |
82 | be used for information about that object. For example, a | |
83 | function may have a property list that includes information about | |
84 | the source file in which it is defined. | |
85 | ||
86 | Property lists are implemented as assq lists (@pxref{Association Lists}). | |
87 | ||
88 | Currently, property lists are implemented differently for procedures and | |
89 | closures than for other kinds of objects. Therefore, when manipulating | |
90 | a property list associated with a procedure object, use the | |
91 | @code{procedure} functions; otherwise, use the @code{object} functions. | |
92 | ||
8f85c0c6 NJ |
93 | @deffn {Scheme Procedure} object-properties obj |
94 | @deffnx {C Function} scm_object_properties (obj) | |
a0e07ba4 NJ |
95 | Return @var{obj}'s property list. |
96 | @end deffn | |
97 | ||
8f85c0c6 NJ |
98 | @deffn {Scheme Procedure} set-object-properties! obj alist |
99 | @deffnx {C Function} scm_set_object_properties_x (obj, alist) | |
a0e07ba4 NJ |
100 | Set @var{obj}'s property list to @var{alist}. |
101 | @end deffn | |
102 | ||
8f85c0c6 NJ |
103 | @deffn {Scheme Procedure} object-property obj key |
104 | @deffnx {C Function} scm_object_property (obj, key) | |
a0e07ba4 NJ |
105 | Return the property of @var{obj} with name @var{key}. |
106 | @end deffn | |
107 | ||
8f85c0c6 NJ |
108 | @deffn {Scheme Procedure} set-object-property! obj key value |
109 | @deffnx {C Function} scm_set_object_property_x (obj, key, value) | |
a0e07ba4 NJ |
110 | In @var{obj}'s property list, set the property named @var{key} |
111 | to @var{value}. | |
112 | @end deffn | |
113 | ||
114 | [Interface bug: there should be a second level of interface in which | |
115 | the user provides a "property table" that is possibly private.] | |
116 | ||
117 | ||
118 | @node Primitive Properties | |
119 | @section Primitive Properties | |
120 | ||
8f85c0c6 NJ |
121 | @deffn {Scheme Procedure} primitive-make-property not_found_proc |
122 | @deffnx {C Function} scm_primitive_make_property (not_found_proc) | |
a0e07ba4 NJ |
123 | Create a @dfn{property token} that can be used with |
124 | @code{primitive-property-ref} and @code{primitive-property-set!}. | |
125 | See @code{primitive-property-ref} for the significance of | |
126 | @var{not_found_proc}. | |
127 | @end deffn | |
128 | ||
8f85c0c6 NJ |
129 | @deffn {Scheme Procedure} primitive-property-ref prop obj |
130 | @deffnx {C Function} scm_primitive_property_ref (prop, obj) | |
a0e07ba4 NJ |
131 | Return the property @var{prop} of @var{obj}. When no value |
132 | has yet been associated with @var{prop} and @var{obj}, call | |
133 | @var{not-found-proc} instead (see @code{primitive-make-property}) | |
134 | and use its return value. That value is also associated with | |
135 | @var{obj} via @code{primitive-property-set!}. When | |
136 | @var{not-found-proc} is @code{#f}, use @code{#f} as the | |
137 | default value of @var{prop}. | |
138 | @end deffn | |
139 | ||
8f85c0c6 NJ |
140 | @deffn {Scheme Procedure} primitive-property-set! prop obj val |
141 | @deffnx {C Function} scm_primitive_property_set_x (prop, obj, val) | |
a0e07ba4 NJ |
142 | Associate @var{code} with @var{prop} and @var{obj}. |
143 | @end deffn | |
144 | ||
8f85c0c6 NJ |
145 | @deffn {Scheme Procedure} primitive-property-del! prop obj |
146 | @deffnx {C Function} scm_primitive_property_del_x (prop, obj) | |
a0e07ba4 NJ |
147 | Remove any value associated with @var{prop} and @var{obj}. |
148 | @end deffn | |
149 | ||
150 | ||
151 | @node Sorting | |
152 | @section Sorting | |
153 | ||
154 | @c FIXME::martin: Review me! | |
155 | ||
156 | @cindex sorting | |
157 | @cindex sorting lists | |
158 | @cindex sorting vectors | |
159 | ||
160 | Sorting is very important in computer programs. Therefore, Guile comes | |
161 | with several sorting procedures built-in. As always, procedures with | |
162 | names ending in @code{!} are side-effecting, that means that they may | |
163 | modify their parameters in order to produce their results. | |
164 | ||
165 | The first group of procedures can be used to merge two lists (which must | |
166 | be already sorted on their own) and produce sorted lists containing | |
167 | all elements of the input lists. | |
168 | ||
8f85c0c6 NJ |
169 | @deffn {Scheme Procedure} merge alist blist less |
170 | @deffnx {C Function} scm_merge (alist, blist, less) | |
171 | Merge two already sorted lists into one. | |
172 | Given two lists @var{alist} and @var{blist}, such that | |
173 | @code{(sorted? alist less?)} and @code{(sorted? blist less?)}, | |
174 | return a new list in which the elements of @var{alist} and | |
a0e07ba4 NJ |
175 | @var{blist} have been stably interleaved so that |
176 | @code{(sorted? (merge alist blist less?) less?)}. | |
8f85c0c6 | 177 | Note: this does _not_ accept vectors. |
a0e07ba4 NJ |
178 | @end deffn |
179 | ||
8f85c0c6 NJ |
180 | @deffn {Scheme Procedure} merge! alist blist less |
181 | @deffnx {C Function} scm_merge_x (alist, blist, less) | |
a0e07ba4 NJ |
182 | Takes two lists @var{alist} and @var{blist} such that |
183 | @code{(sorted? alist less?)} and @code{(sorted? blist less?)} and | |
184 | returns a new list in which the elements of @var{alist} and | |
185 | @var{blist} have been stably interleaved so that | |
186 | @code{(sorted? (merge alist blist less?) less?)}. | |
187 | This is the destructive variant of @code{merge} | |
188 | Note: this does _not_ accept vectors. | |
189 | @end deffn | |
190 | ||
191 | The following procedures can operate on sequences which are either | |
192 | vectors or list. According to the given arguments, they return sorted | |
193 | vectors or lists, respectively. The first of the following procedures | |
194 | determines whether a sequence is already sorted, the other sort a given | |
195 | sequence. The variants with names starting with @code{stable-} are | |
196 | special in that they maintain a special property of the input sequences: | |
197 | If two or more elements are the same according to the comparison | |
198 | predicate, they are left in the same order as they appeared in the | |
199 | input. | |
200 | ||
8f85c0c6 NJ |
201 | @deffn {Scheme Procedure} sorted? items less |
202 | @deffnx {C Function} scm_sorted_p (items, less) | |
a0e07ba4 NJ |
203 | Return @code{#t} iff @var{items} is a list or a vector such that |
204 | for all 1 <= i <= m, the predicate @var{less} returns true when | |
205 | applied to all elements i - 1 and i | |
206 | @end deffn | |
207 | ||
8f85c0c6 NJ |
208 | @deffn {Scheme Procedure} sort items less |
209 | @deffnx {C Function} scm_sort (items, less) | |
a0e07ba4 NJ |
210 | Sort the sequence @var{items}, which may be a list or a |
211 | vector. @var{less} is used for comparing the sequence | |
212 | elements. This is not a stable sort. | |
213 | @end deffn | |
214 | ||
8f85c0c6 NJ |
215 | @deffn {Scheme Procedure} sort! items less |
216 | @deffnx {C Function} scm_sort_x (items, less) | |
a0e07ba4 NJ |
217 | Sort the sequence @var{items}, which may be a list or a |
218 | vector. @var{less} is used for comparing the sequence | |
219 | elements. The sorting is destructive, that means that the | |
220 | input sequence is modified to produce the sorted result. | |
221 | This is not a stable sort. | |
222 | @end deffn | |
223 | ||
8f85c0c6 NJ |
224 | @deffn {Scheme Procedure} stable-sort items less |
225 | @deffnx {C Function} scm_stable_sort (items, less) | |
a0e07ba4 NJ |
226 | Sort the sequence @var{items}, which may be a list or a |
227 | vector. @var{less} is used for comparing the sequence elements. | |
228 | This is a stable sort. | |
229 | @end deffn | |
230 | ||
8f85c0c6 NJ |
231 | @deffn {Scheme Procedure} stable-sort! items less |
232 | @deffnx {C Function} scm_stable_sort_x (items, less) | |
a0e07ba4 NJ |
233 | Sort the sequence @var{items}, which may be a list or a |
234 | vector. @var{less} is used for comparing the sequence elements. | |
235 | The sorting is destructive, that means that the input sequence | |
236 | is modified to produce the sorted result. | |
237 | This is a stable sort. | |
238 | @end deffn | |
239 | ||
240 | The procedures in the last group only accept lists or vectors as input, | |
241 | as their names indicate. | |
242 | ||
8f85c0c6 NJ |
243 | @deffn {Scheme Procedure} sort-list items less |
244 | @deffnx {C Function} scm_sort_list (items, less) | |
a0e07ba4 NJ |
245 | Sort the list @var{items}, using @var{less} for comparing the |
246 | list elements. This is a stable sort. | |
247 | @end deffn | |
248 | ||
8f85c0c6 NJ |
249 | @deffn {Scheme Procedure} sort-list! items less |
250 | @deffnx {C Function} scm_sort_list_x (items, less) | |
a0e07ba4 NJ |
251 | Sort the list @var{items}, using @var{less} for comparing the |
252 | list elements. The sorting is destructive, that means that the | |
253 | input list is modified to produce the sorted result. | |
254 | This is a stable sort. | |
255 | @end deffn | |
256 | ||
8f85c0c6 NJ |
257 | @deffn {Scheme Procedure} restricted-vector-sort! vec less startpos endpos |
258 | @deffnx {C Function} scm_restricted_vector_sort_x (vec, less, startpos, endpos) | |
a0e07ba4 NJ |
259 | Sort the vector @var{vec}, using @var{less} for comparing |
260 | the vector elements. @var{startpos} and @var{endpos} delimit | |
261 | the range of the vector which gets sorted. The return value | |
262 | is not specified. | |
263 | @end deffn | |
264 | ||
265 | ||
266 | @node Copying | |
267 | @section Copying Deep Structures | |
268 | ||
269 | @c FIXME::martin: Review me! | |
270 | ||
271 | The procedures for copying lists (@pxref{Lists}) only produce a flat | |
272 | copy of the input list, and currently Guile does not even contain | |
273 | procedures for copying vectors. @code{copy-tree} can be used for these | |
274 | application, as it does not only copy the spine of a list, but also | |
275 | copies any pairs in the cars of the input lists. | |
276 | ||
8f85c0c6 NJ |
277 | @deffn {Scheme Procedure} copy-tree obj |
278 | @deffnx {C Function} scm_copy_tree (obj) | |
a0e07ba4 NJ |
279 | Recursively copy the data tree that is bound to @var{obj}, and return a |
280 | pointer to the new data structure. @code{copy-tree} recurses down the | |
281 | contents of both pairs and vectors (since both cons cells and vector | |
282 | cells may point to arbitrary objects), and stops recursing when it hits | |
283 | any other object. | |
284 | @end deffn | |
285 | ||
286 | ||
287 | @node General Conversion | |
288 | @section General String Conversion | |
289 | ||
290 | @c FIXME::martin: Review me! | |
291 | ||
292 | When debugging Scheme programs, but also for providing a human-friendly | |
293 | interface, a procedure for converting any Scheme object into string | |
294 | format is very useful. Conversion from/to strings can of course be done | |
295 | with specialized procedures when the data type of the object to convert | |
296 | is known, but with this procedure, it is often more comfortable. | |
297 | ||
298 | @code{object->string} converts an object by using a print procedure for | |
299 | writing to a string port, and then returning the resulting string. | |
300 | Converting an object back from the string is only possible if the object | |
301 | type has a read syntax and the read syntax is preserved by the printing | |
302 | procedure. | |
303 | ||
8f85c0c6 NJ |
304 | @deffn {Scheme Procedure} object->string obj [printer] |
305 | @deffnx {C Function} scm_object_to_string (obj, printer) | |
a0e07ba4 NJ |
306 | Return a Scheme string obtained by printing @var{obj}. |
307 | Printing function can be specified by the optional second | |
308 | argument @var{printer} (default: @code{write}). | |
309 | @end deffn | |
310 | ||
311 | ||
4c731ece NJ |
312 | @node Hooks |
313 | @section Hooks | |
314 | @tpindex Hooks | |
315 | ||
316 | @c FIXME::martin: Review me! | |
317 | ||
318 | A hook is basically a list of procedures to be called at well defined | |
319 | points in time. Hooks are used internally for several debugging | |
320 | facilities, but they can be used in user code, too. | |
321 | ||
322 | Hooks are created with @code{make-hook}, then procedures can be added to | |
323 | a hook with @code{add-hook!} or removed with @code{remove-hook!} or | |
324 | @code{reset-hook!}. The procedures stored in a hook can be invoked with | |
325 | @code{run-hook}. | |
326 | ||
327 | @menu | |
328 | * Hook Examples:: Hook usage by example. | |
329 | * Hook Reference:: Reference of all hook procedures. | |
330 | @end menu | |
331 | ||
332 | @node Hook Examples | |
333 | @subsection Hook Examples | |
334 | ||
335 | Hook usage is shown by some examples in this section. First, we will | |
336 | define a hook of arity 2 --- that is, the procedures stored in the hook | |
337 | will have to accept two arguments. | |
338 | ||
339 | @lisp | |
340 | (define hook (make-hook 2)) | |
341 | hook | |
342 | @result{} #<hook 2 40286c90> | |
343 | @end lisp | |
344 | ||
345 | Now we are ready to add some procedures to the newly created hook with | |
346 | @code{add-hook!}. In the following example, two procedures are added, | |
347 | which print different messages and do different things with their | |
348 | arguments. When the procedures have been added, we can invoke them | |
349 | using @code{run-hook}. | |
350 | ||
351 | @lisp | |
352 | (add-hook! hook (lambda (x y) | |
353 | (display "Foo: ") | |
354 | (display (+ x y)) | |
355 | (newline))) | |
356 | (add-hook! hook (lambda (x y) | |
357 | (display "Bar: ") | |
358 | (display (* x y)) | |
359 | (newline))) | |
360 | (run-hook hook 3 4) | |
361 | @print{} Bar: 12 | |
362 | @print{} Foo: 7 | |
363 | @end lisp | |
364 | ||
365 | Note that the procedures are called in reverse order than they were | |
366 | added. This can be changed by providing the optional third argument | |
367 | on the second call to @code{add-hook!}. | |
368 | ||
369 | @lisp | |
370 | (add-hook! hook (lambda (x y) | |
371 | (display "Foo: ") | |
372 | (display (+ x y)) | |
373 | (newline))) | |
374 | (add-hook! hook (lambda (x y) | |
375 | (display "Bar: ") | |
376 | (display (* x y)) | |
377 | (newline)) | |
378 | #t) ; @r{<- Change here!} | |
379 | (run-hook hook 3 4) | |
380 | @print{} Foo: 7 | |
381 | @print{} Bar: 12 | |
382 | @end lisp | |
383 | ||
384 | @node Hook Reference | |
385 | @subsection Hook Reference | |
386 | ||
387 | When a hook is created with @code{make-hook}, you can supply the arity | |
388 | of the procedures which can be added to the hook. The arity defaults to | |
389 | zero. All procedures of a hook must have the same arity, and when the | |
390 | procedures are invoked using @code{run-hook}, the number of arguments | |
391 | must match the arity of the procedures. | |
392 | ||
393 | The order in which procedures are added to a hook matters. If the third | |
394 | parameter to @var{add-hook!} is omitted or is equal to @code{#f}, the | |
395 | procedure is added in front of the procedures which might already be on | |
396 | that hook, otherwise the procedure is added at the end. The procedures | |
397 | are always called from first to last when they are invoked via | |
398 | @code{run-hook}. | |
399 | ||
400 | When calling @code{hook->list}, the procedures in the resulting list are | |
401 | in the same order as they would have been called by @code{run-hook}. | |
402 | ||
403 | @deffn {Scheme Procedure} make-hook [n_args] | |
404 | @deffnx {C Function} scm_make_hook (n_args) | |
405 | Create a hook for storing procedure of arity @var{n_args}. | |
406 | @var{n_args} defaults to zero. The returned value is a hook | |
407 | object to be used with the other hook procedures. | |
408 | @end deffn | |
409 | ||
410 | @deffn {Scheme Procedure} hook? x | |
411 | @deffnx {C Function} scm_hook_p (x) | |
412 | Return @code{#t} if @var{x} is a hook, @code{#f} otherwise. | |
413 | @end deffn | |
414 | ||
415 | @deffn {Scheme Procedure} hook-empty? hook | |
416 | @deffnx {C Function} scm_hook_empty_p (hook) | |
417 | Return @code{#t} if @var{hook} is an empty hook, @code{#f} | |
418 | otherwise. | |
419 | @end deffn | |
420 | ||
421 | @deffn {Scheme Procedure} add-hook! hook proc [append_p] | |
422 | @deffnx {C Function} scm_add_hook_x (hook, proc, append_p) | |
423 | Add the procedure @var{proc} to the hook @var{hook}. The | |
424 | procedure is added to the end if @var{append_p} is true, | |
425 | otherwise it is added to the front. The return value of this | |
426 | procedure is not specified. | |
427 | @end deffn | |
428 | ||
429 | @deffn {Scheme Procedure} remove-hook! hook proc | |
430 | @deffnx {C Function} scm_remove_hook_x (hook, proc) | |
431 | Remove the procedure @var{proc} from the hook @var{hook}. The | |
432 | return value of this procedure is not specified. | |
433 | @end deffn | |
434 | ||
435 | @deffn {Scheme Procedure} reset-hook! hook | |
436 | @deffnx {C Function} scm_reset_hook_x (hook) | |
437 | Remove all procedures from the hook @var{hook}. The return | |
438 | value of this procedure is not specified. | |
439 | @end deffn | |
440 | ||
441 | @deffn {Scheme Procedure} run-hook hook . args | |
442 | @deffnx {C Function} scm_run_hook (hook, args) | |
443 | Apply all procedures from the hook @var{hook} to the arguments | |
444 | @var{args}. The order of the procedure application is first to | |
445 | last. The return value of this procedure is not specified. | |
446 | @end deffn | |
447 | ||
448 | @deffn {Scheme Procedure} hook->list hook | |
449 | @deffnx {C Function} scm_hook_to_list (hook) | |
450 | Convert the procedure list of @var{hook} to a list. | |
451 | @end deffn | |
452 | ||
453 | ||
a0e07ba4 NJ |
454 | @c Local Variables: |
455 | @c TeX-master: "guile.texi" | |
456 | @c End: |