diff options
Diffstat (limited to 'doc/ref/scheme-utility.texi')
-rw-r--r-- | doc/ref/scheme-utility.texi | 156 |
1 files changed, 110 insertions, 46 deletions
diff --git a/doc/ref/scheme-utility.texi b/doc/ref/scheme-utility.texi index bcec4b881..cc1556c31 100644 --- a/doc/ref/scheme-utility.texi +++ b/doc/ref/scheme-utility.texi @@ -10,8 +10,7 @@ applications, they are collected in a @dfn{utility} chapter. @menu * Equality:: When are two values `the same'? -* Property Lists:: Managing meta-information about Scheme objects. -* Primitive Properties:: A modern interface to object properties. +* Object Properties:: A modern interface to object properties. * Sorting:: Sort utility procedures. * Copying:: Copying deep structures. * General Conversion:: Converting objects to strings. @@ -75,48 +74,78 @@ terminate if its arguments are circular data structures. @end deffn -@node Property Lists -@section Property Lists +@node Object Properties +@section Object Properties -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. +It's often useful to associate a piece of additional information with a +Scheme object even though that object does not have a dedicated slot +available in which the additional information could be stored. Object +properties allow you to do just that. -Property lists are implemented as assq lists (@pxref{Association Lists}). +An object property is most commonly used to associate one kind of +additional information with each instance of a class of similar Scheme +objects. For example, all procedures have a `name' property, which +stores the name of the variable in which the procedure was stored by a +@code{define} expression, or @code{#f} if the procedure wasn't created +by that kind of expression. -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. +Guile's representation of an object property is a procedure-with-setter +(@pxref{Procedures with Setters}) that can be used with the generalized +form of @code{set!} (REFFIXME) to set and retrieve that property for any +Scheme object. So, setting a property looks like this: -@deffn {Scheme Procedure} object-properties obj -@deffnx {C Function} scm_object_properties (obj) -Return @var{obj}'s property list. -@end deffn +@lisp +(set! (my-property obj1) value-for-obj1) +(set! (my-property obj2) value-for-obj2) +@end lisp -@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 +@noindent +And retrieving values of the same property looks like this: -@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 +@lisp +(my-property obj1) +@result{} +value-for-obj1 -@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}. +(my-property obj2) +@result{} +value-for-obj2 +@end lisp + +To create an object property in the first place, use the +@code{make-object-property} procedure: + +@lisp +(define my-property (make-object-property)) +@end lisp + +@deffn {Scheme Procedure} make-object-property +Create and return an object property. An object property is a +procedure-with-setter that can be called in two ways. @code{(set! +(@var{property} @var{obj}) @var{val})} sets @var{obj}'s @var{property} +to @var{val}. @code{(@var{property} @var{obj})} returns the current +setting of @var{obj}'s @var{property}. @end deffn -[Interface bug: there should be a second level of interface in which -the user provides a "property table" that is possibly private.] +A single object property created by @code{make-object-property} can +associate distinct property values with all Scheme values that are +distinguishable by @code{eq?} (including, for example, integers). + +Internally, object properties are implemented using a weak key hash +table. This means that, as long as a Scheme value with property values +is protected from garbage collection, its property values are also +protected. When the Scheme value is collected, its entry in the +property table is removed and so the (ex-) property values are no longer +protected by the table. + +@menu +* Property Primitives:: Low level property implementation. +* Old-fashioned Properties:: An older approach to properties. +@end menu -@node Primitive Properties -@section Primitive Properties +@node Property Primitives +@subsection Low Level Property Implementation. @deffn {Scheme Procedure} primitive-make-property not_found_proc @deffnx {C Function} scm_primitive_make_property (not_found_proc) @@ -148,6 +177,41 @@ Remove any value associated with @var{prop} and @var{obj}. @end deffn +@node Old-fashioned Properties +@subsection An Older Approach to Properties + +Traditionally, Lisp systems provide a different object property +interface to that provided by @code{make-object-property}, in which the +object property that is being set or retrieved is indicated by a symbol. + +Guile includes this older kind of interface as well, but it may well be +removed in a future release, as it is less powerful than +@code{make-object-property} and so increases the size of the Guile +library for no benefit. (And it is trivial to write a compatibility +layer in Scheme.) + +@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 + + @node Sorting @section Sorting @@ -349,13 +413,13 @@ 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)) +(add-hook! hook (lambda (x y) + (display "Foo: ") + (display (+ x y)) (newline))) -(add-hook! hook (lambda (x y) - (display "Bar: ") - (display (* x y)) +(add-hook! hook (lambda (x y) + (display "Bar: ") + (display (* x y)) (newline))) (run-hook hook 3 4) @print{} Bar: 12 @@ -367,14 +431,14 @@ 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)) +(add-hook! hook (lambda (x y) + (display "Foo: ") + (display (+ x y)) (newline))) -(add-hook! hook (lambda (x y) - (display "Bar: ") - (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 |