diff options
author | Marius Vollmer <mvo@zagadka.de> | 2004-08-02 12:29:00 +0000 |
---|---|---|
committer | Marius Vollmer <mvo@zagadka.de> | 2004-08-02 12:29:00 +0000 |
commit | 07d83abe7b8b617e4bb70a08efc0c0f6999fa0cc (patch) | |
tree | 34c8a7b9d98000169379038be8551ed44c0bdb83 /doc/ref/api-utility.texi | |
parent | 237be238424f1b6d130799ad931ba6fa8504a97c (diff) | |
download | guile-07d83abe7b8b617e4bb70a08efc0c0f6999fa0cc.tar.gz |
* scheme-binding.texi: Renamed to api-binding.texi.
* scheme-compound.texi: Renamed to api-compound.texi.
* scheme-control.texi: Renamed to api-control.texi.
* scheme-data.texi: Renamed to api-data.texi.
* scheme-debug.texi: Renamed to api-debug.texi.
* deprecated.texi: Renamed to api-deprecated.texi.
* scheme-evaluation.texi: Renamed to api-evaluation.texi.
* ref-init.texi: Renamed to api-init.texi.
* scheme-io.texi: Renamed to api-io.texi.
* scheme-memory.texi: Renamed to api-memory.texi.
* scheme-modules.texi: Renamed to api-modules.texi.
* scheme-options.texi: Renamed to api-options.texi.
* scm.texi: Renamed to api-overview.texi.
* scheme-procedures.texi: Renamed to api-procedures.texi.
* scheme-scheduling.texi: Renamed to api-scheduling.texi.
* scheme-scm.texi: Renamed to api-scm.texi.
* scheme-smobs.texi: Renamed to api-smobs.texi.
* scheme-snarf.texi: Renamed to api-snarf.texi.
* scheme-translation.texi: Renamed to api-translation.texi.
* scheme-utility.texi: Renamed to api-utility.texi.
* debugging.texi: Renamed to scheme-debugging.texi.
* scripts.texi: Renamed to scheme-scripts.texi.
* program.texi: Renamed to libguile-program.texi.
Diffstat (limited to 'doc/ref/api-utility.texi')
-rw-r--r-- | doc/ref/api-utility.texi | 762 |
1 files changed, 762 insertions, 0 deletions
diff --git a/doc/ref/api-utility.texi b/doc/ref/api-utility.texi new file mode 100644 index 000000000..8cc662fa7 --- /dev/null +++ b/doc/ref/api-utility.texi @@ -0,0 +1,762 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Utility Functions +@section 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'? +* Object 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 +@subsection 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 +@deffnx {C Function} scm_eq_p (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 + +@deftypefn {C Function} int scm_is_eq (SCM x, SCM y) +Return @code{1} when @var{x} and @var{y} are equal in the sense of +@code{eq?}, else return @code{0}. +@end deftypefn + +@rnindex eqv? +@deffn {Scheme Procedure} eqv? x y +@deffnx {C Function} scm_eqv_p (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 +@deffnx {C Function} scm_equal_p (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 Object Properties +@subsection Object Properties + +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. + +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. + +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: + +@lisp +(set! (my-property obj1) value-for-obj1) +(set! (my-property obj2) value-for-obj2) +@end lisp + +@noindent +And retrieving values of the same property looks like this: + +@lisp +(my-property obj1) +@result{} +value-for-obj1 + +(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 + +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 Property Primitives +@subsubsection Low Level Property Implementation. + +@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}, +the @var{not-found-proc} from @var{prop} is used. A call +@code{(@var{not-found-proc} @var{prop} @var{obj})} is made and the +result set as the property value. If @var{not-found-proc} is +@code{#f} then @code{#f} is the property value. +@end deffn + +@deffn {Scheme Procedure} primitive-property-set! prop obj val +@deffnx {C Function} scm_primitive_property_set_x (prop, obj, val) +Set the property @var{prop} of @var{obj} to @var{val}. +@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 Old-fashioned Properties +@subsubsection 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 +@subsection 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 +@subsection 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 +@subsection 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 +@subsection Hooks +@tpindex Hooks + +A hook is a list of procedures to be called at well defined points in +time. Typically, an application provides a hook @var{h} and promises +its users that it will call all of the procedures in @var{h} at a +defined point in the application's processing. By adding its own +procedure to @var{h}, an application user can tap into or even influence +the progress of the application. + +Guile itself provides several such hooks for debugging and customization +purposes: these are listed in a subsection below. + +When an application first creates a hook, it needs to know how many +arguments will be passed to the hook's procedures when the hook is run. +The chosen number of arguments (which may be none) is declared when the +hook is created, and all the procedures that are added to that hook must +be capable of accepting that number of arguments. + +A hook is created using @code{make-hook}. A procedure can be added to +or removed from a hook using @code{add-hook!} or @code{remove-hook!}, +and all of a hook's procedures can be removed together using +@code{reset-hook!}. When an application wants to run a hook, it does so +using @code{run-hook}. + +@menu +* Hook Example:: Hook usage by example. +* Hook Reference:: Reference of all hook procedures. +* C Hooks:: Hooks for use from C code. +* GC Hooks:: Garbage collection hooks. +* REPL Hooks:: Hooks into the Guile REPL. +@end menu + + +@node Hook Example +@subsubsection Hook Usage by Example + +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. + +@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))) +@end lisp + +Once the procedures have been added, we can invoke the hook using +@code{run-hook}. + +@lisp +(run-hook hook 3 4) +@print{} Bar: 12 +@print{} Foo: 7 +@end lisp + +Note that the procedures are called in the reverse of the order with +which they were added. This is because the default behaviour of +@code{add-hook!} is to add its procedure to the @emph{front} of the +hook's procedure list. You can force @code{add-hook!} to add its +procedure to the @emph{end} of the list instead by providing a third +@code{#t} 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 +@subsubsection Hook Reference + +When you create a hook with @code{make-hook}, you must specify the arity +of the procedures which can be added to the hook. If the arity is not +given explicitly as an argument to @code{make-hook}, it defaults to +zero. All procedures of a given hook must have the same arity, and when +the procedures are invoked using @code{run-hook}, the number of +arguments passed must match the arity specified at hook creation time. + +The order in which procedures are added to a hook matters. If the third +parameter to @code{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 the front to the end of the list when they are +invoked via @code{run-hook}. + +The ordering of the list of procedures returned by @code{hook->list} +matches the order in which those procedures would be called if the hook +was run using @code{run-hook}. + +Note that the C functions in the following entries are for handling +@dfn{Scheme-level} hooks in C. There are also @dfn{C-level} hooks which +have their own interface (@pxref{C Hooks}). + +@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} hook->list hook +@deffnx {C Function} scm_hook_to_list (hook) +Convert the procedure list of @var{hook} to a list. +@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 + +If, in C code, you are certain that you have a hook object and well +formed argument list for that hook, you can also use +@code{scm_c_run_hook}, which is identical to @code{scm_run_hook} but +does no type checking. + +@deftypefn {C Function} void scm_c_run_hook (SCM hook, SCM args) +The same as @code{scm_run_hook} but without any type checking to confirm +that @var{hook} is actually a hook object and that @var{args} is a +well-formed list matching the arity of the hook. +@end deftypefn + +For C code, @code{SCM_HOOKP} is a faster alternative to +@code{scm_hook_p}: + +@deftypefn {C Macro} int SCM_HOOKP (x) +Return 1 if @var{x} is a Scheme-level hook, 0 otherwise. +@end deftypefn + + +@subsubsection Handling Scheme-level hooks from C code + +Here is an example of how to handle Scheme-level hooks from C code using +the above functions. + +@example +if (scm_is_true (scm_hook_p (obj))) + /* handle Scheme-level hook using C functions */ + scm_reset_hook_x (obj); +else + /* do something else (obj is not a hook) */ +@end example + + +@node C Hooks +@subsubsection Hooks For C Code. + +The hooks already described are intended to be populated by Scheme-level +procedures. In addition to this, the Guile library provides an +independent set of interfaces for the creation and manipulation of hooks +that are designed to be populated by functions implemented in C. + +The original motivation here was to provide a kind of hook that could +safely be invoked at various points during garbage collection. +Scheme-level hooks are unsuitable for this purpose as running them could +itself require memory allocation, which would then invoke garbage +collection recursively @dots{} However, it is also the case that these +hooks are easier to work with than the Scheme-level ones if you only +want to register C functions with them. So if that is mainly what your +code needs to do, you may prefer to use this interface. + +To create a C hook, you should allocate storage for a structure of type +@code{scm_t_c_hook} and then initialize it using @code{scm_c_hook_init}. + +@deftp {C Type} scm_t_c_hook +Data type for a C hook. The internals of this type should be treated as +opaque. +@end deftp + +@deftp {C Enum} scm_t_c_hook_type +Enumeration of possible hook types, which are: + +@table @code +@item SCM_C_HOOK_NORMAL +@vindex SCM_C_HOOK_NORMAL +Type of hook for which all the registered functions will always be called. +@item SCM_C_HOOK_OR +@vindex SCM_C_HOOK_OR +Type of hook for which the sequence of registered functions will be +called only until one of them returns C true (a non-NULL pointer). +@item SCM_C_HOOK_AND +@vindex SCM_C_HOOK_AND +Type of hook for which the sequence of registered functions will be +called only until one of them returns C false (a NULL pointer). +@end table +@end deftp + +@deftypefn {C Function} void scm_c_hook_init (scm_t_c_hook *hook, void *hook_data, scm_t_c_hook_type type) +Initialize the C hook at memory pointed to by @var{hook}. @var{type} +should be one of the values of the @code{scm_t_c_hook_type} enumeration, +and controls how the hook functions will be called. @var{hook_data} is +a closure parameter that will be passed to all registered hook functions +when they are called. +@end deftypefn + +To add or remove a C function from a C hook, use @code{scm_c_hook_add} +or @code{scm_c_hook_remove}. A hook function must expect three +@code{void *} parameters which are, respectively: + +@table @var +@item hook_data +The hook closure data that was specified at the time the hook was +initialized by @code{scm_c_hook_init}. + +@item func_data +The function closure data that was specified at the time that that +function was registered with the hook by @code{scm_c_hook_add}. + +@item data +The call closure data specified by the @code{scm_c_hook_run} call that +runs the hook. +@end table + +@deftp {C Type} scm_t_c_hook_function +Function type for a C hook function: takes three @code{void *} +parameters and returns a @code{void *} result. +@end deftp + +@deftypefn {C Function} void scm_c_hook_add (scm_t_c_hook *hook, scm_t_c_hook_function func, void *func_data, int appendp) +Add function @var{func}, with function closure data @var{func_data}, to +the C hook @var{hook}. The new function is appended to the hook's list +of functions if @var{appendp} is non-zero, otherwise prepended. +@end deftypefn + +@deftypefn {C Function} void scm_c_hook_remove (scm_t_c_hook *hook, scm_t_c_hook_function func, void *func_data) +Remove function @var{func}, with function closure data @var{func_data}, +from the C hook @var{hook}. @code{scm_c_hook_remove} checks both +@var{func} and @var{func_data} so as to allow for the same @var{func} +being registered multiple times with different closure data. +@end deftypefn + +Finally, to invoke a C hook, call the @code{scm_c_hook_run} function +specifying the hook and the call closure data for this run: + +@deftypefn {C Function} {void *} scm_c_hook_run (scm_t_c_hook *hook, void *data) +Run the C hook @var{hook} will call closure data @var{data}. Subject to +the variations for hook types @code{SCM_C_HOOK_OR} and +@code{SCM_C_HOOK_AND}, @code{scm_c_hook_run} calls @var{hook}'s +registered functions in turn, passing them the hook's closure data, each +function's closure data, and the call closure data. + +@code{scm_c_hook_run}'s return value is the return value of the last +function to be called. +@end deftypefn + + +@node GC Hooks +@subsubsection Hooks for Garbage Collection + +Whenever Guile performs a garbage collection, it calls the following +hooks in the order shown. + +@defvr {C Hook} scm_before_gc_c_hook +C hook called at the very start of a garbage collection, after setting +@code{scm_gc_running_p} to 1, but before entering the GC critical +section. + +If garbage collection is blocked because @code{scm_block_gc} is +non-zero, GC exits early soon after calling this hook, and no further +hooks will be called. +@end defvr + +@defvr {C Hook} scm_before_mark_c_hook +C hook called before beginning the mark phase of garbage collection, +after the GC thread has entered a critical section. +@end defvr + +@defvr {C Hook} scm_before_sweep_c_hook +C hook called before beginning the sweep phase of garbage collection. +This is the same as at the end of the mark phase, since nothing else +happens between marking and sweeping. +@end defvr + +@defvr {C Hook} scm_after_sweep_c_hook +C hook called after the end of the sweep phase of garbage collection, +but while the GC thread is still inside its critical section. +@end defvr + +@defvr {C Hook} scm_after_gc_c_hook +C hook called at the very end of a garbage collection, after the GC +thread has left its critical section. +@end defvr + +@defvr {Scheme Hook} after-gc-hook +@vindex scm_after_gc_hook +Scheme hook with arity 0. This hook is run asynchronously +(@pxref{Asyncs}) soon after the GC has completed and any other events +that were deferred during garbage collection have been processed. (Also +accessible from C with the name @code{scm_after_gc_hook}.) +@end defvr + +All the C hooks listed here have type @code{SCM_C_HOOK_NORMAL}, are +initialized with hook closure data NULL, are are invoked by +@code{scm_c_hook_run} with call closure data NULL. + +@cindex guardians, testing for GC'd objects +The Scheme hook @code{after-gc-hook} is particularly useful in +conjunction with guardians (@pxref{Guardians}). Typically, if you are +using a guardian, you want to call the guardian after garbage collection +to see if any of the objects added to the guardian have been collected. +By adding a thunk that performs this call to @code{after-gc-hook}, you +can ensure that your guardian is tested after every garbage collection +cycle. + + +@node REPL Hooks +@subsubsection Hooks into the Guile REPL + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: |