123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786 |
- @c -*-texinfo-*-
- @c This is part of the GNU Guile Reference Manual.
- @c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2011, 2012, 2013, 2014, 2020
- @c Free Software Foundation, Inc.
- @c See the file guile.texi for copying conditions.
- @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
- @cindex sameness
- @cindex equality
- There are three kinds of core equality predicates in Scheme, described
- below. The same kinds of comparisons arise in other functions, like
- @code{memq} and friends (@pxref{List Searching}).
- For all three tests, objects of different types are never equal. So
- for instance a list and a vector are not @code{equal?}, even if their
- contents are the same. Exact and inexact numbers are considered
- different types too, and are hence not equal even if their values are
- the same.
- @code{eq?} tests just for the same object (essentially a pointer
- comparison). This is fast, and can be used when searching for a
- particular object, or when working with symbols or keywords (which are
- always unique objects).
- @code{eqv?} extends @code{eq?} to look at the value of numbers and
- characters. It can for instance be used somewhat like @code{=}
- (@pxref{Comparison}) but without an error if one operand isn't a
- number.
- @code{equal?} goes further, it looks (recursively) into the contents
- of lists, vectors, etc. This is good for instance on lists that have
- been read or calculated in various places and are the same, just not
- made up of the same pairs. Such lists look the same (when printed),
- and @code{equal?} will consider them the same.
- @sp 1
- @deffn {Scheme Procedure} eq? x y
- @deffnx {C Function} scm_eq_p (x, y)
- @rnindex eq?
- Return @code{#t} if @var{x} and @var{y} are the same object, except
- for numbers and characters. For example,
- @example
- (define x (vector 1 2 3))
- (define y (vector 1 2 3))
- (eq? x x) @result{} #t
- (eq? x y) @result{} #f
- @end example
- Numbers and characters are not equal to any other object, but the
- problem is they're not necessarily @code{eq?} to themselves either.
- This is even so when the number comes directly from a variable,
- @example
- (let ((n (+ 2 3)))
- (eq? n n)) @result{} *unspecified*
- @end example
- Generally @code{eqv?} below should be used when comparing numbers or
- characters. @code{=} (@pxref{Comparison}) or @code{char=?}
- (@pxref{Characters}) can be used too.
- It's worth noting that end-of-list @code{()}, @code{#t}, @code{#f}, a
- symbol of a given name, and a keyword of a given name, are unique
- objects. There's just one of each, so for instance no matter how
- @code{()} arises in a program, it's the same object and can be
- compared with @code{eq?},
- @example
- (define x (cdr '(123)))
- (define y (cdr '(456)))
- (eq? x y) @result{} #t
- (define x (string->symbol "foo"))
- (eq? x 'foo) @result{} #t
- @end example
- @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?}, otherwise return @code{0}.
- @findex ==
- The @code{==} operator should not be used on @code{SCM} values, an
- @code{SCM} is a C type which cannot necessarily be compared using
- @code{==} (@pxref{The SCM Type}).
- @end deftypefn
- @sp 1
- @deffn {Scheme Procedure} eqv? x y
- @deffnx {C Function} scm_eqv_p (x, y)
- @rnindex eqv?
- Return @code{#t} if @var{x} and @var{y} are the same object, or for
- characters and numbers the same value.
- On objects except characters and numbers, @code{eqv?} is the same as
- @code{eq?} above, it's true if @var{x} and @var{y} are the same
- object.
- If @var{x} and @var{y} are numbers or characters, @code{eqv?} compares
- their type and value. An exact number is not @code{eqv?} to an
- inexact number (even if their value is the same).
- @example
- (eqv? 3 (+ 1 2)) @result{} #t
- (eqv? 1 1.0) @result{} #f
- @end example
- @end deffn
- @sp 1
- @deffn {Scheme Procedure} equal? x y
- @deffnx {C Function} scm_equal_p (x, y)
- @rnindex equal?
- Return @code{#t} if @var{x} and @var{y} are the same type, and their
- contents or value are equal.
- For a pair, string, vector, array or structure, @code{equal?} compares the
- contents, and does so using the same @code{equal?} recursively,
- so a deep structure can be traversed.
- @example
- (equal? (list 1 2 3) (list 1 2 3)) @result{} #t
- (equal? (list 1 2 3) (vector 1 2 3)) @result{} #f
- @end example
- For other objects, @code{equal?} compares as per @code{eqv?} above,
- which means characters and numbers are compared by type and value (and
- like @code{eqv?}, exact and inexact numbers are not @code{equal?},
- even if their value is the same).
- @example
- (equal? 3 (+ 1 2)) @result{} #t
- (equal? 1 1.0) @result{} #f
- @end example
- Hash tables are currently only compared as per @code{eq?}, so two
- different tables are not @code{equal?}, even if their contents are the
- same.
- @code{equal?} does not support circular data structures, it may go
- into an infinite loop if asked to compare two circular lists or
- similar.
- GOOPS object types (@pxref{GOOPS}), including foreign object types
- (@pxref{Defining New Foreign Object Types}), can have an @code{equal?}
- implementation specialized on two values of the same type. If
- @code{equal?} is called on two GOOPS objects of the same type,
- @code{equal?} will dispatch out to a generic function. This lets an
- application traverse the contents or control what is considered
- @code{equal?} for two objects of such a type. If there's no such
- handler, the default is to just compare as per @code{eq?}.
- @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.
- 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?} (ruling out numeric values).
- 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.
- Guile also implements a more traditional Lispy interface to properties,
- in which each object has an list of key-value pairs associated with it.
- Properties in that list are keyed by symbols. This is a legacy
- interface; you should use weak hash tables or object properties instead.
- @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} if @var{items} is a list or vector such that,
- for each element @var{x} and the next element @var{y} of
- @var{items}, @code{(@var{less} @var{y} @var{x})} returns
- @code{#f}. Otherwise return @code{#f}.
- @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} (inclusively) and
- @var{endpos} (exclusively) delimit
- the range of the vector which gets sorted. The return value
- is not specified.
- @end deffn
- @node Copying
- @subsection Copying Deep Structures
- 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. The @code{(ice-9 copy-tree)} module
- contains a @code{copy-tree} function that can be used for this purpose,
- as it does not only copy the spine of a list, but also copies any pairs
- in the cars of the input lists.
- @example
- (use-modules (ice-9 copy-tree))
- @end example
- @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
- 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 arg @dots{}
- @deffnx {C Function} scm_run_hook (hook, args)
- Apply all procedures from the hook @var{hook} to the arguments @var{arg}
- @enddots{}. 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
- @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 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:
|