This is guile-ref.info, produced by Makeinfo version 3.12a from guile-ref.texi. INFO-DIR-SECTION Scheme Programming START-INFO-DIR-ENTRY * guile-ref: (guile-ref). The Guile Reference Manual. END-INFO-DIR-ENTRY Guile Reference Manual Copyright (C) 1996 Free Software Foundation Copyright (C) 1997 Free Software Foundation Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.  File: guile-ref.info, Node: Dynamic Libraries, Prev: First-class Modules, Up: Module Internals Dynamic Libraries ================= Often you will want to extend Guile by linking it with some existing system library. For example, linking Guile with a `curses' or `termcap' library would be useful if you want to implement a full-screen user interface for a Guile application. However, if you were to link Guile with these libraries at compile time, it would bloat the interpreter considerably, affecting everyone on the system even if the new libraries are useful only to you. Also, every time a new library is installed, you would have to reconfigure, recompile and relink Guile merely in order to provide a new interface. Many Unix systems permit you to get around this problem by using "dynamic loading". When a new library is linked, it can be made a "dynamic library" by passing certain switches to the linker. A dynamic library does not need to be linked with an executable image at link time; instead, the executable may choose to load it dynamically at run time. This is a powerful concept that permits an executable to link itself with almost any library without reconfiguration, if it has been written properly. Guile's dynamic linking functions make it relatively easy to write a module that incorporates code from third-party object code libraries. -- primitive: dynamic-link library-file Open the dynamic library LIBRARY-FILE. A library handle representing the opened library is returned; this handle should be used as the LIB argument to the following functions. -- primitive: dynamic-object? obj Return `#t' if OBJ is a dynamic library handle, or `#f' otherwise. -- primitive: dynamic-unlink lib Unlink the library represented by LIBRARY-HANDLE, and remove any imported symbols from the address space. -- primitive: dynamic-func func lib Import the symbol FUNC from LIB (a dynamic library handle). A "function handle" representing the imported function is returned. -- primitive: dynamic-call lib-thunk lib Call LIB-THUNK, a procedure of no arguments. If LIB-THUNK is a string, it is assumed to be a symbol found in the dynamic library LIB and is fetched with `dynamic-func'. Otherwise, it should be a function handle returned by a previous call to `dynamic-func'. The return value is unspecified. -- primitive: dynamic-args-call proc lib args Call PROC, a dynamically loaded function, passing it the argument list ARGS (a list of strings). As with `dynamic-call', PROC should be either a function handle or a string, in which case it is first fetched from LIB with `dynamic-func'. PROC is assumed to return an integer, which is used as the return value from `dynamic-args-call'. -- primitive: c-registered-modules Return a list of the object code modules that have been imported into the current Guile process. Each element of the list is a pair whose car is the name of the module (as it might be used by `use-modules', for instance), and whose cdr is the function handle for that module's initializer function. -- primitive: c-clear-registered-modules Destroy the list of modules registered with the current Guile process. The return value is unspecified. *Warning:* this function does not actually unlink or deallocate these modules, but only destroys the records of which modules have been loaded. It should therefore be used only by module bookkeeping operations. [FIXME: provide a brief example here of writing the C hooks for an object code module, and using dynamic-link and dynamic-call to load the module.]  File: guile-ref.info, Node: Dynamic Linking from Marius, Next: Dynamic Wind, Prev: Module Internals, Up: Top Dynamic Linking from Marius *************************** Most modern Unices have something called "shared libraries". This ordinarily means that they have the capability to share the executable image of a library between several running programs to save memory and disk space. But generally, shared libraries give a lot of additional flexibility compared to the traditional static libraries. In fact, calling them `dynamic' libraries is as correct as calling them `shared'. Shared libraries really give you a lot of flexibility in addition to the memory and disk space savings. When you link a program against a shared library, that library is not closely incorporated into the final executable. Instead, the executable of your program only contains enough information to find the needed shared libraries when the program is actually run. Only then, when the program is starting, is the final step of the linking process performed. This means that you need not recompile all programs when you install a new, only slightly modified version of a shared library. The programs will pick up the changes automatically the next time they are run. Now, when all the necessary machinery is there to perform part of the linking at run-time, why not take the next step and allow the programmer to explicitly take advantage of it from within his program? Of course, many operating systems that support shared libraries do just that, and chances are that Guile will allow you to access this feature from within your Scheme programs. As you might have guessed already, this feature is called "dynamic linking"(1) As with many aspects of Guile, there is a low-level way to access the dynamic linking apparatus, and a more high-level interface that integrates dynamically linked libraries into the module system. * Menu: * Low level dynamic linking:: * Compiled Code Modules:: * Dynamic Linking and Compiled Code Modules:: ---------- Footnotes ---------- (1) Some people also refer to the final linking stage at program startup as `dynamic linking', so if you want to make yourself perfectly clear, it is probably best to use the more technical term "dlopening", as suggested by Gordon Matzigkeit in his libtool documentation.  File: guile-ref.info, Node: Low level dynamic linking, Next: Compiled Code Modules, Up: Dynamic Linking from Marius Low level dynamic linking ========================= When using the low level procedures to do your dynamic linking, you have complete control over which library is loaded when and what get's done with it. -- primitive: dynamic-link library Find the shared library denoted by LIBRARY (a string) and link it into the running Guile application. When everything works out, return a Scheme object suitable for representing the linked object file. Otherwise an error is thrown. How object files are searched is system dependent. Normally, LIBRARY is just the name of some shared library file that will be searched for in the places where shared libraries usually reside, such as in `/usr/lib' and `/usr/local/lib'. -- primitive: dynamic-object? val Determine whether VAL represents a dynamically linked object file. -- primitive: dynamic-unlink dynobj Unlink the indicated object file from the application. The argument DYNOBJ should be one of the values returned by `dynamic-link'. When `dynamic-unlink' has been called on DYNOBJ, it is no longer usable as an argument to the functions below and you will get type mismatch errors when you try to. -- primitive: dynamic-func function dynobj Search the C function indicated by FUNCTION (a string or symbol) in DYNOBJ and return some Scheme object that can later be used with `dynamic-call' to actually call this function. Right now, these Scheme objects are formed by casting the address of the function to `long' and converting this number to its Scheme representation. Regardless whether your C compiler prepends an underscore `_' to the global names in a program, you should *not* include this underscore in FUNCTION. Guile knows whether the underscore is needed or not and will add it when necessary. -- primitive: dynamic-call function dynobj Call the C function indicated by FUNCTION and DYNOBJ. The function is passed no arguments and its return value is ignored. When FUNCTION is something returned by `dynamic-func', call that function and ignore DYNOBJ. When FUNCTION is a string (or symbol, etc.), look it up in DYNOBJ; this is equivalent to (dynamic-call (dynamic-func FUNCTION DYNOBJ #f)) Interrupts are deferred while the C function is executing (with `SCM_DEFER_INTS'/`SCM_ALLOW_INTS'). -- primitive: dynamic-args-call function dynobj args Call the C function indicated by FUNCTION and DYNOBJ, just like `dynamic-call', but pass it some arguments and return its return value. The C function is expected to take two arguments and return an `int', just like `main': int c_func (int argc, char **argv); The parameter ARGS must be a list of strings and is converted into an array of `char *'. The array is passed in ARGV and its size in ARGC. The return value is converted to a Scheme number and returned from the call to `dynamic-args-call'. When dynamic linking is disabled or not supported on your system, the above functions throw errors, but they are still available. Here is a small example that works on GNU/Linux: (define libc-obj (dynamic-link "libc.so")) libc-obj => # (dynamic-args-call 'rand libc-obj '()) => 269167349 (dynamic-unlink libc-obj) libc-obj => # As you can see, after calling `dynamic-unlink' on a dynamically linked library, it is marked as `(unlinked)' and you are no longer able to use it with `dynamic-call', etc. Whether the library is really removed from you program is system-dependent and will generally not happen when some other parts of your program still use it. In the example above, `libc' is almost certainly not removed from your program because it is badly needed by almost everything. The functions to call a function from a dynamically linked library, `dynamic-call' and `dynamic-args-call', are not very powerful. They are mostly intended to be used for calling specially written initialization functions that will then add new primitives to Guile. For example, we do not expect that you will dynamically link `libX11' with `dynamic-link' and then construct a beautiful graphical user interface just by using `dynamic-call' and `dynamic-args-call'. Instead, the usual way would be to write a special Guile<->X11 glue library that has intimate knowledge about both Guile and X11 and does whatever is necessary to make them inter-operate smoothly. This glue library could then be dynamically linked into a vanilla Guile interpreter and activated by calling its initialization function. That function would add all the new types and primitives to the Guile interpreter that it has to offer. >From this setup the next logical step is to integrate these glue libraries into the module system of Guile so that you can load new primitives into a running system just as you can load new Scheme code. There is, however, another possibility to get a more thorough access to the functions contained in a dynamically linked library. Anthony Green has written `libffi', a library that implements a "foreign function interface" for a number of different platforms. With it, you can extend the Spartan functionality of `dynamic-call' and `dynamic-args-call' considerably. There is glue code available in the Guile contrib archive to make `libffi' accessible from Guile.  File: guile-ref.info, Node: Compiled Code Modules, Next: Dynamic Linking and Compiled Code Modules, Prev: Low level dynamic linking, Up: Dynamic Linking from Marius Putting Compiled Code into Modules ================================== The new primitives that you add to Guile with `gh_new_procedure' or with any of the other mechanisms are normally placed into the same module as all the other builtin procedures (like `display'). However, it is also possible to put new primitives into their own module. The mechanism for doing so is not very well thought out and is likely to change when the module system of Guile itself is revised, but it is simple and useful enough to document it as it stands. What `gh_new_procedure' and the functions used by the snarfer really do is to add the new primitives to whatever module is the _current module_ when they are called. This is analogous to the way Scheme code is put into modules: the `define-module' expression at the top of a Scheme source file creates a new module and makes it the current module while the rest of the file is evaluated. The `define' expressions in that file then add their new definitions to this current module. Therefore, all we need to do is to make sure that the right module is current when calling `gh_new_procedure' for our new primitives. Unfortunately, there is not yet an easy way to access the module system from C, so we are better off with a more indirect approach. Instead of adding our primitives at initialization time we merely register with Guile that we are ready to provide the contents of a certain module, should it ever be needed. -- Function: void scm_register_module_xxx (char *NAME, void (*INITFUNC)(void)) Register with Guile that INITFUNC will provide the contents of the module NAME. The function INITFUNC should perform the usual initialization actions for your new primitives, like calling `gh_new_procedure' or including the file produced by the snarfer. When INITFUNC is called, the current module is a newly created module with a name as indicated by NAME. Each definition that is added to it will be automatically exported. The string NAME indicates the hierachical name of the new module. It should consist of the individual components of the module name separated by single spaces. That is, the Scheme module name `(foo bar)', which is a list, should be written as `"foo bar"' for the NAME parameter. You can call `scm_register_module_xxx' at any time, even before Guile has been initialized. This might be useful when you want to put the call to it in some initialization code that is magically called before main, like constructors for global C++ objects. An example for `scm_register_module_xxx' appears in the next section. Now, instead of calling the initialization function at program startup, you should simply call `scm_register_module_xxx' and pass it the initialization function. When the named module is later requested by Scheme code with `use-modules' for example, Guile will notice that it knows how to create this module and will call the initialization function at the right time in the right context.  File: guile-ref.info, Node: Dynamic Linking and Compiled Code Modules, Prev: Compiled Code Modules, Up: Dynamic Linking from Marius Dynamic Linking and Compiled Code Modules ========================================= The most interesting application of dynamically linked libraries is probably to use them for providing _compiled code modules_ to Scheme programs. As much fun as programming in Scheme is, every now and then comes the need to write some low-level C stuff to make Scheme even more fun. Not only can you put these new primitives into their own module (see the previous section), you can even put them into a shared library that is only then linked to your running Guile image when it is actually needed. An example will hopefully make everything clear. Suppose we want to make the Bessel functions of the C library available to Scheme in the module `(math bessel)'. First we need to write the appropriate glue code to convert the arguments and return values of the functions from Scheme to C and back. Additionally, we need a function that will add them to the set of Guile primitives. Because this is just an example, we will only implement this for the `j0' function, tho. #include #include SCM j0_wrapper (SCM x) { return gh_double2scm (j0 (gh_scm2double (x))); } void init_math_bessel () { gh_new_procedure1_0 ("j0", j0_wrapper); } We can already try to bring this into action by manually calling the low level functions for performing dynamic linking. The C source file needs to be compiled into a shared library. Here is how to do it on GNU/Linux, please refer to the `libtool' documentation for how to create dynamically linkable libraries portably. gcc -shared -o libbessel.so -fPIC bessel.c Now fire up Guile: (define bessel-lib (dynamic-link "./libbessel.so")) (dynamic-call "init_math_bessel" bessel-lib) (j0 2) => 0.223890779141236 The filename `./libbessel.so' should be pointing to the shared library produced with the `gcc' command above, of course. The second line of the Guile interaction will call the `init_math_bessel' function which in turn will register the C function `j0_wrapper' with the Guile interpreter under the name `j0'. This function becomes immediately available and we can call it from Scheme. Fun, isn't it? But we are only half way there. This is what `apropos' has to say about `j0': (apropos 'j0) -| the-root-module: j0 # As you can see, `j0' is contained in the root module, where all the other Guile primitives like `display', etc live. In general, a primitive is put into whatever module is the "current module" at the time `gh_new_procedure' is called. To put `j0' into its own module named `(math bessel)', we need to make a call to `scm_register_module_xxx'. Additionally, to have Guile perform the dynamic linking automatically, we need to put `libbessel.so' into a place where Guile can find it. The call to `scm_register_module_xxx' should be contained in a specially named "module init function". Guile knows about this special name and will call that function automatically after having linked in the shared library. For our example, we add the following code to `bessel.c': void scm_init_math_bessel_module () { scm_register_module_xxx ("math bessel", init_math_bessel); } The general pattern for the name of a module init function is: `scm_init_', followed by the name of the module where the individual hierarchical components are concatenated with underscores, followed by `_module'. It should call `scm_register_module_xxx' with the correct module name and the appropriate initialization function. When that initialization function will be called, a newly created module with the right name will be the _current module_ so that all definitions that the initialization functions makes will end up in the correct module. After `libbessel.so' has been rebuild, we need to place the shared library into the right place. When Guile tries to autoload the `(math bessel)' module, it looks not only for a file called `math/bessel.scm' in its `%load-path', but also for `math/libbessel.so'. So all we need to do is to create a directory called `math' somewhere in Guile's `%load-path' and place `libbessel.so' there. Normally, the current directory `.' is in the `%load-path', so we just use that for this example. % mkdir maths % cd maths % ln -s ../libbessel.so . % cd .. % guile guile> (use-modules (math bessel)) guile> (j0 2) 0.223890779141236 guile> (apropos 'j0) -| bessel: j0 # That's it! Note that we used a symlink to make `libbessel.so' appear in the right spot. This is probably not a bad idea in general. The directories that the `%load-path' normally contains are supposed to contain only architecture independent files. They are not really the right place for a shared library. You might want to install the libraries somewhere below `exec_prefix' and then symlink to them from the architecture independent directory. This will at least work on heterogenous systems where the architecture dependent stuff resides in the same place on all machines (which seems like a good idea to me anyway).  File: guile-ref.info, Node: Dynamic Wind, Next: Threads and Dynamic Roots, Prev: Dynamic Linking from Marius, Up: Top Dynamic Wind ************ [FIXME: this is pasted in from Tom Lord's original guile.texi and should be reviewed] -- primitive: dynamic-wind in-guard thunk out-guard All three arguments must be 0-argument procedures. IN-GUARD is called, then THUNK, then OUT-GUARD. If, any time during the execution of THUNK, the continuation of the `dynamic-wind' expression is escaped non-locally, OUT-GUARD is called. If the continuation of the dynamic-wind is re-entered, IN-GUARD is called. Thus IN-GUARD and OUT-GUARD may be called any number of times. (define x 'normal-binding) => x (define a-cont (call-with-current-continuation (lambda (escape) (let ((old-x x)) (dynamic-wind ;; in-guard: ;; (lambda () (set! x 'special-binding)) ;; thunk ;; (lambda () (display x) (newline) (call-with-current-continuation escape) (display x) (newline) x) ;; out-guard: ;; (lambda () (set! x old-x))))))) ;; Prints: special-binding ;; Evaluates to: => a-cont x => normal-binding (a-cont #f) ;; Prints: special-binding ;; Evaluates to: => a-cont ;; the value of the (define a-cont...) x => normal-binding a-cont => special-binding  File: guile-ref.info, Node: Threads and Dynamic Roots, Next: Reflection, Prev: Dynamic Wind, Up: Top Threads and Dynamic Roots ************************* [FIXME: This is pasted in from Tom Lord's original guile.texi chapter plus the Cygnus programmer's manual; it should be *very* carefully reviewed and largely reorganized.] * Menu: * Dynamic Roots:: * Threads::  File: guile-ref.info, Node: Dynamic Roots, Next: Threads, Up: Threads and Dynamic Roots Dynamic Roots ============= A "dynamic root" is a root frame of Scheme evaluation. The top-level repl, for example, is an instance of a dynamic root. Each dynamic root has its own chain of dynamic-wind information. Each has its own set of continuations, jump-buffers, and pending CATCH statements which are inaccessible from the dynamic scope of any other dynamic root. In a thread-based system, each thread has its own dynamic root. Therefore, continuations created by one thread may not be invoked by another. Even in a single-threaded system, it is sometimes useful to create a new dynamic root. For example, if you want to apply a procedure, but to not allow that procedure to capture the current continuation, calling the procedure under a new dynamic root will do the job. -- primitive: call-with-dynamic-root thunk handler Evaluate (THUNK) in a new dynamic context, returning its value. If an error occurs during evaluation, apply HANDLER to the arguments to the throw, just as `throw' would. If this happens, HANDLER is called outside the scope of the new root -- it is called in the same dynamic context in which `call-with-dynamic-root' was evaluated. If THUNK captures a continuation, the continuation is rooted at the call to THUNK. In particular, the call to `call-with-dynamic-root' is not captured. Therefore, `call-with-dynamic-root' always returns at most one time. Before calling THUNK, the dynamic-wind chain is un-wound back to the root and a new chain started for THUNK. Therefore, this call may not do what you expect: ;; Almost certainly a bug: (with-output-to-port some-port (lambda () (call-with-dynamic-root (lambda () (display 'fnord) (newline)) (lambda (errcode) errcode)))) The problem is, on what port will `fnord\n' be displayed? You might expect that because of the `with-output-to-port' that it will be displayed on the port bound to `some-port'. But it probably won't -- before evaluating the thunk, dynamic winds are unwound, including those created by `with-output-to-port'. So, the standard output port will have been re-set to its default value before `display' is evaluated. (This function was added to Guile mostly to help calls to functions in C libraries that can not tolerate non-local exits or calls that return multiple times. If such functions call back to the interpreter, it should be under a new dynamic root.) -- primitive: dynamic-root Return an object representing the current dynamic root. These objects are only useful for comparison using `eq?'. They are currently represented as numbers, but your code should in no way depend on this. -- procedure: quit [exit_val] Throw back to the error handler of the current dynamic root. If integer EXIT_VAL is specified and if Guile is being used stand-alone and if quit is called from the initial dynamic-root, EXIT_VAL becomes the exit status of the Guile process and the process exits. When Guile is run interactively, errors are caught from within the read-eval-print loop. An error message will be printed and `abort' called. A default set of signal handlers is installed, e.g., to allow user interrupt of the interpreter. It is possible to switch to a "batch mode", in which the interpreter will terminate after an error and in which all signals cause their default actions. Switching to batch mode causes any handlers installed from Scheme code to be removed. An example of where this is useful is after forking a new process intended to run non-interactively. -- procedure: batch-mode? Returns a boolean indicating whether the interpreter is in batch mode. -- procedure: set-batch-mode?! arg If ARG is true, switches the interpreter to batch mode. The `#f' case has not been implemented.  File: guile-ref.info, Node: Threads, Prev: Dynamic Roots, Up: Threads and Dynamic Roots Threads ======= *[NOTE: this chapter was written for Cygnus Guile and has not yet been updated for the Guile 1.x release.]* Here is a the reference for Guile's threads. In this chapter I simply quote verbatim Tom Lord's description of the low-level primitives written in C (basically an interface to the POSIX threads library) and Anthony Green's description of the higher-level thread procedures written in scheme. When using Guile threads, keep in mind that each guile thread is executed in a new dynamic root. * Menu: * Low level thread primitives:: * Higher level thread procedures::  File: guile-ref.info, Node: Low level thread primitives, Next: Higher level thread procedures, Up: Threads Low level thread primitives --------------------------- -- primitive: call-with-new-thread thunk error-thunk Evaluate (THUNK) in a new thread, and new dynamic context, returning a new thread object representing the thread. If an error occurs during evaluation, call error-thunk, passing it an error code describing the condition. [Error codes are currently meaningless integers. In the future, real values will be specified.] If this happens, the error-thunk is called outside the scope of the new root -- it is called in the same dynamic context in which with-new-thread was evaluated, but not in the callers thread. All the evaluation rules for dynamic roots apply to threads. -- primitive: join-thread thread Suspend execution of the calling thread until the target THREAD terminates, unless the target THREAD has already terminated. -- primitive: yield If one or more threads are waiting to execute, calling yield forces an immediate context switch to one of them. Otherwise, yield has no effect. -- primitive: make-mutex Create a new mutex object. -- primitive: lock-mutex mutex Lock MUTEX. If the mutex is already locked, the calling thread blocks until the mutex becomes available. The function returns when the calling thread owns the lock on MUTEX. -- primitive: unlock-mutex mutex Unlocks MUTEX if the calling thread owns the lock on MUTEX. Calling unlock-mutex on a mutex not owned by the current thread results in undefined behaviour. Once a mutex has been unlocked, one thread blocked on MUTEX is awakened and grabs the mutex lock.  File: guile-ref.info, Node: Higher level thread procedures, Prev: Low level thread primitives, Up: Threads Higher level thread procedures ------------------------------ -- primitive: call-with-new-thread thunk error-thunk Evaluate (THUNK) in a new thread, and new dynamic context, returning a new thread object representing the thread. If an error occurs during evaluation, call error-thunk, passing it an error code describing the condition. [Error codes are currently meaningless integers. In the future, real values will be specified.] If this happens, the error-thunk is called outside the scope of the new root -- it is called in the same dynamic context in which with-new-thread was evaluated, but not in the callers thread. All the evaluation rules for dynamic roots apply to threads. -- primitive: join-thread thread Suspend execution of the calling thread until the target THREAD terminates, unless the target THREAD has already terminated. -- primitive: yield If one or more threads are waiting to execute, calling yield forces an immediate context switch to one of them. Otherwise, yield has no effect. -- primitive: make-mutex Create a new mutex object. -- primitive: lock-mutex mutex Lock MUTEX. If the mutex is already locked, the calling thread blocks until the mutex becomes available. The function returns when the calling thread owns the lock on MUTEX. -- primitive: unlock-mutex mutex Unlocks MUTEX if the calling thread owns the lock on MUTEX. Calling unlock-mutex on a mutex not owned by the current thread results in undefined behaviour. Once a mutex has been unlocked, one thread blocked on MUTEX is awakened and grabs the mutex lock.  File: guile-ref.info, Node: Reflection, Next: Weak References, Prev: Threads and Dynamic Roots, Up: Top Reflection ********** [FIXME: this is pasted in from Tom Lord's original guile.texi and should be reviewed] * Menu: * eval:: * Tag Values::  File: guile-ref.info, Node: eval, Next: Tag Values, Up: Reflection eval ====  File: guile-ref.info, Node: Tag Values, Prev: eval, Up: Reflection Tag Values ==========  File: guile-ref.info, Node: Weak References, Next: Garbage Collection, Prev: Reflection, Up: Top Weak References *************** [FIXME: This chapter is based on Mikael Djurfeldt's answer to a question by Michael Livshin. Any mistakes are not theirs, of course. ] Weak references let you attach bookkeeping information to data so that the additional information automatically disappears when the original data is no longer in use and gets garbage collected. In a weak key hash, the hash entry for that key disappears as soon as the key is no longer referneced from anywhere else. For weak value hashes, the same happens as soon as the value is no longer in use. Entries in a doubly weak hash disappear when either the key or the value are not used anywhere else anymore. Property lists offer the same kind of functionality as weak key hashes in many situations. (*note Property Lists::.) Here's an example (a little bit strained perhaps, but one of the examples is actually used in Guile): Assume that you're implementing a debugging system where you want to associate information about filename and position of source code expressions with the expressions themselves. Hashtables can be used for that, but if you use ordinary hash tables it will be impossible for the scheme interpreter to "forget" old source when, for example, a file is reloaded. To implement the mapping from source code expressions to positional information it is necessary to use weak-key tables since we don't want the expressions to be remembered just because they are in our table. To implement a mapping from source file line numbers to source code expressions you would use a weak-value table. To implement a mapping from source code expressions to the procedures they constitute a doubly-weak table has to be used. Weak key hashes =============== -- primitive: make-weak-key-hash-table size -- primitive: make-weak-value-hash-table size -- primitive: make-doubly-weak-hash-table size Return a weak hash table with SIZE buckets. As with any hash table, choosing a good size for the table requires some caution. You can modify weak hash tables in exactly the same way you would modify regular hash tables. (*note Hash Tables::.) -- primitive: weak-key-hash-table? obj -- primitive: weak-value-hash-table? obj -- primitive: doubly-weak-hash-table? obj Return #T if OBJ is the specified weak hash table. Note that a doubly weak hash table is neither a weak key nor a weak value hash table. Weak vectors ============ Weak vectors are mainly useful in Guile's implementation of weak hash tables. -- primitive: make-weak-vector size [fill] Return a weak vector with SIZE elements. If the optional argument FILL is given, all entries in the vector will be set to FILL. The default value for FILL is the empty list. -- primitive: weak-vector . rest -- primitive: list->weak-vector l Construct a weak vector from a list: `weak-vector' uses the list of its arguments while `list->weak-vector' uses its only argument L (a list) to construct a weak vector the same way `vector->list' would. -- primitive: weak-vector? obj Return #T if OBJ is a weak vector. Note that all weak hashes are also weak vectors.  File: guile-ref.info, Node: Garbage Collection, Next: Configuration Data, Prev: Weak References, Up: Top Garbage Collection ****************** [FIXME: this is pasted in from Tom Lord's original guile.texi and should be reviewed] -- primitive: gc Scans all of SCM objects and reclaims for further use those that are no longer accessible. -- primitive: gc-stats Returns an association list of statistics about Guile's current use of storage. -- primitive: object-address obj Return an integer that for the lifetime of OBJ is uniquely returned by this function for OBJ  File: guile-ref.info, Node: Configuration Data, Next: Internal Debugging Interface, Prev: Garbage Collection, Up: Top Configuration Data ****************** It is often useful to have site-specific information about the current Guile installation. This chapter describes how to find out about Guile's configuration at run time. -- primitive: version -- primitive: major-version -- primitive: minor-version Return a string describing Guile's version number, or its major or minor version numbers, respectively. (version) => "1.3a" (major-version) => "1" (minor-version) => "3a" -- primitive: libguile-config-stamp Return a string describing the date on which `libguile' was configured. This is used to determine whether the Guile core interpreter and the ice-9 runtime have grown out of date with one another. -- primitive: %package-data-dir Return the name of the directory where Scheme packages, modules and libraries are kept. On most Unix systems, this will be `/usr/local/share/guile'. -- Variable: %load-path Return the list of directories which should be searched for Scheme modules and libraries.  File: guile-ref.info, Node: Internal Debugging Interface, Next: Conventions, Prev: Configuration Data, Up: Top Internal Debugging Interface **************************** --- The name of this chapter needs to clearly distinguish it from the appendix describing the debugger UI. The intro should have a pointer to the UI appendix.  File: guile-ref.info, Node: Conventions, Next: Ports and File Descriptors, Prev: Internal Debugging Interface, Up: Top POSIX Interface Conventions *************************** The low-level interfaces are designed to give Scheme programs access to as much functionality as possible from the underlying Unix system. They can be used to implement higher level intefaces such as the Scheme shell *Note The Scheme shell (scsh)::. Generally there is a single procedure for each corresponding Unix facility. There are some exceptions, such as procedures implemented for speed and convenience in Scheme with no primitive Unix equivalent, e.g., `copy-file'. The interfaces are intended as far as possible to be portable across different versions of Unix, so that Scheme programmers don't need to be concerned with implementation differences. In some cases procedures which can't be implemented (or reimplemented) on particular systems may become no-ops, or perform limited actions. In other cases they may throw errors. It should be possible to use the feature system to determine what functionality is available. General naming conventions are as follows: * The Scheme name is often identical to the name of the underlying Unix facility. * Underscores in Unix names are converted to hyphens. * Procedures which destructively modify Scheme data gain exclaimation marks, e.g., `recv!'. * Predicates (returning only `#t' or `#f') have question marks added, e.g., `access?'. * Some names are changed to avoid conflict with dissimilar interfaces defined by scsh, e.g., `primitive-fork'. * Unix preprocessor names such as `EPERM' or `R_OK' are converted to Scheme variables of the same name (underscores are not replaced with hyphens). Most of the procedures can be relied on to return a well-specified value. Unexpected conditions are handled by raising exceptions. There are a few procedures which return a special value if they don't succeed, e.g., `getenv' returns `#f' if it the requested string is not found in the environment. These cases will be noted in the documentation. For ways to deal with exceptions, *Note Exceptions::. Errors which the C-library would report by returning a NULL pointer or through some other means are reported by raising a `system-error' exception. The value of the Unix `errno' variable is available in the data passed by the exception. Accessing the global errno value directly would be unreliable due to continuations, interrupts or multiple threads.