This is guile.info, produced by makeinfo version 7.1 from guile.texi.

This reference manual documents Guile, GNU's Ubiquitous Intelligent
Language for Extensions.  This is edition 1.1 corresponding to Guile
1.8.8.

   Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010 Free Software Foundation.

   Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2 or
any later version published by the Free Software Foundation; with the no
Invariant Sections, with the Front-Cover Texts being "A GNU Manual," and
with the Back-Cover Text "You are free to copy and modify this GNU
Manual.".  A copy of the license is included in the section entitled
"GNU Free Documentation License".
INFO-DIR-SECTION The Algorithmic Language Scheme
START-INFO-DIR-ENTRY
* Guile Reference: (guile).     The Guile reference manual.
END-INFO-DIR-ENTRY


File: guile.info,  Node: Parallel Forms,  Prev: Fluids and Dynamic States,  Up: Scheduling

5.17.9 Parallel forms
---------------------

The functions described in this section are available from

     (use-modules (ice-9 threads))

 -- syntax: parallel expr1 ... exprN
     Evaluate each EXPR expression in parallel, each in its own thread.
     Return the results as a set of N multiple values (*note Multiple
     Values::).

 -- syntax: letpar ((var1 expr1) ... (varN exprN)) body...
     Evaluate each EXPR in parallel, each in its own thread, then bind
     the results to the corresponding VAR variables and evaluate BODY.

     ‘letpar’ is like ‘let’ (*note Local Bindings::), but all the
     expressions for the bindings are evaluated in parallel.

 -- Scheme Procedure: par-map proc lst1 ... lstN
 -- Scheme Procedure: par-for-each proc lst1 ... lstN
     Call PROC on the elements of the given lists.  ‘par-map’ returns a
     list comprising the return values from PROC.  ‘par-for-each’
     returns an unspecified value, but waits for all calls to complete.

     The PROC calls are ‘(PROC ELEM1 ... ELEMN)’, where each ELEM is
     from the corresponding LST.  Each LST must be the same length.  The
     calls are made in parallel, each in its own thread.

     These functions are like ‘map’ and ‘for-each’ (*note List
     Mapping::), but make their PROC calls in parallel.

 -- Scheme Procedure: n-par-map n proc lst1 ... lstN
 -- Scheme Procedure: n-par-for-each n proc lst1 ... lstN
     Call PROC on the elements of the given lists, in the same way as
     ‘par-map’ and ‘par-for-each’ above, but use no more than N threads
     at any one time.  The order in which calls are initiated within
     that threads limit is unspecified.

     These functions are good for controlling resource consumption if
     PROC calls might be costly, or if there are many to be made.  On a
     dual-CPU system for instance N=4 might be enough to keep the CPUs
     utilized, and not consume too much memory.

 -- Scheme Procedure: n-for-each-par-map n sproc pproc lst1 ... lstN
     Apply PPROC to the elements of the given lists, and apply SPROC to
     each result returned by PPROC.  The final return value is
     unspecified, but all calls will have been completed before
     returning.

     The calls made are ‘(SPROC (PPROC ELEM1 ... ELEMN))’, where each
     ELEM is from the corresponding LST.  Each LST must have the same
     number of elements.

     The PPROC calls are made in parallel, in separate threads.  No more
     than N threads are used at any one time.  The order in which PPROC
     calls are initiated within that limit is unspecified.

     The SPROC calls are made serially, in list element order, one at a
     time.  PPROC calls on later elements may execute in parallel with
     the SPROC calls.  Exactly which thread makes each SPROC call is
     unspecified.

     This function is designed for individual calculations that can be
     done in parallel, but with results needing to be handled serially,
     for instance to write them to a file.  The N limit on threads
     controls system resource usage when there are many calculations or
     when they might be costly.

     It will be seen that ‘n-for-each-par-map’ is like a combination of
     ‘n-par-map’ and ‘for-each’,

          (for-each sproc (n-par-map n pproc lst1 ... lstN))

     But the actual implementation is more efficient since each SPROC
     call, in turn, can be initiated once the relevant PPROC call has
     completed, it doesn't need to wait for all to finish.


File: guile.info,  Node: Options and Config,  Next: Translation,  Prev: Scheduling,  Up: API Reference

5.18 Configuration, Features and Runtime Options
================================================

Why is my Guile different from your Guile?  There are three kinds of
possible variation:

   • build differences -- different versions of the Guile source code,
     installation directories, configuration flags that control pieces
     of functionality being included or left out, etc.

   • differences in dynamically loaded code -- behaviour and features
     provided by modules that can be dynamically loaded into a running
     Guile

   • different runtime options -- some of the options that are provided
     for controlling Guile's behaviour may be set differently.

   Guile provides "introspective" variables and procedures to query all
of these possible variations at runtime.  For runtime options, it also
provides procedures to change the settings of options and to obtain
documentation on what the options mean.

* Menu:

* Build Config::                Build and installation configuration.
* Feature Tracking::            Available features in the Guile process.
* Runtime Options::             Controlling Guile's runtime behaviour.


File: guile.info,  Node: Build Config,  Next: Feature Tracking,  Up: Options and Config

5.18.1 Configuration, Build and Installation
--------------------------------------------

The following procedures and variables provide information about how
Guile was configured, built and installed on your system.

 -- Scheme Procedure: version
 -- Scheme Procedure: effective-version
 -- Scheme Procedure: major-version
 -- Scheme Procedure: minor-version
 -- Scheme Procedure: micro-version
 -- C Function: scm_version ()
 -- C Function: scm_effective_version ()
 -- C Function: scm_major_version ()
 -- C Function: scm_minor_version ()
 -- C Function: scm_micro_version ()
     Return a string describing Guile's full version number, effective
     version number, major, minor or micro version number, respectively.
     The ‘effective-version’ function returns the version name that
     should remain unchanged during a stable series.  Currently that
     means that it omits the micro version.  The effective version
     should be used for items like the versioned share directory name
     i.e.  ‘/usr/share/guile/1.6/’

          (version) ⇒ "1.6.0"
          (effective-version) ⇒ "1.6"
          (major-version) ⇒ "1"
          (minor-version) ⇒ "6"
          (micro-version) ⇒ "0"

 -- Scheme Procedure: %package-data-dir
 -- C Function: scm_sys_package_data_dir ()
     Return the name of the directory under which Guile Scheme files in
     general are stored.  On Unix-like systems, this is usually
     ‘/usr/local/share/guile’ or ‘/usr/share/guile’.

 -- Scheme Procedure: %library-dir
 -- C Function: scm_sys_library_dir ()
     Return the name of the directory where the Guile Scheme files that
     belong to the core Guile installation (as opposed to files from a
     3rd party package) are installed.  On Unix-like systems, this is
     usually ‘/usr/local/share/guile/<GUILE_EFFECTIVE_VERSION>’ or
     ‘/usr/share/guile/<GUILE_EFFECTIVE_VERSION>’, for example:
     ‘/usr/local/share/guile/1.6’.

 -- Scheme Procedure: %site-dir
 -- C Function: scm_sys_site_dir ()
     Return the name of the directory where Guile Scheme files specific
     to your site should be installed.  On Unix-like systems, this is
     usually ‘/usr/local/share/guile/site’ or ‘/usr/share/guile/site’.

 -- Variable: %load-path
     List of directories which should be searched for Scheme modules and
     libraries.  ‘%load-path’ is initialized when Guile starts up to
     ‘(list (%site-dir) (%library-dir) (%package-data-dir))’, prepended
     with the contents of the GUILE_LOAD_PATH environment variable, if
     it is set.

 -- Scheme Procedure: parse-path path [tail]
 -- C Function: scm_parse_path (path, tail)
     Parse PATH, which is expected to be a colon-separated string, into
     a list and return the resulting list with TAIL appended.  If PATH
     is ‘#f’, TAIL is returned.

 -- Scheme Procedure: search-path path filename [extensions]
 -- C Function: scm_search_path (path, filename, extensions)
     Search PATH for a directory containing a file named FILENAME.  The
     file must be readable, and not a directory.  If we find one, return
     its full filename; otherwise, return ‘#f’.  If FILENAME is
     absolute, return it unchanged.  If given, EXTENSIONS is a list of
     strings; for each directory in PATH, we search for FILENAME
     concatenated with each EXTENSION.

 -- Variable: %guile-build-info
     Alist of information collected during the building of a particular
     Guile.  Entries can be grouped into one of several categories:
     directories, env vars, and versioning info.

     Briefly, here are the keys in ‘%guile-build-info’, by group:

     directories
          srcdir, top_srcdir, prefix, exec_prefix, bindir, sbindir,
          libexecdir, datadir, sysconfdir, sharedstatedir,
          localstatedir, libdir, infodir, mandir, includedir,
          pkgdatadir, pkglibdir, pkgincludedir
     env vars
          LIBS
     versioning info
          guileversion, libguileinterface, buildstamp

     Values are all strings.  The value for ‘LIBS’ is typically found
     also as a part of "guile-config link" output.  The value for
     ‘guileversion’ has form X.Y.Z, and should be the same as returned
     by ‘(version)’.  The value for ‘libguileinterface’ is libtool
     compatible and has form CURRENT:REVISION:AGE (*note Library
     interface versions: (libtool)Versioning.).  The value for
     ‘buildstamp’ is the output of the date(1) command.

     In the source, ‘%guile-build-info’ is initialized from
     libguile/libpath.h, which is completely generated, so deleting this
     file before a build guarantees up-to-date values for that build.


File: guile.info,  Node: Feature Tracking,  Next: Runtime Options,  Prev: Build Config,  Up: Options and Config

5.18.2 Feature Tracking
-----------------------

Guile has a Scheme level variable ‘*features*’ that keeps track to some
extent of the features that are available in a running Guile.
‘*features*’ is a list of symbols, for example ‘threads’, each of which
describes a feature of the running Guile process.

 -- Variable: *features*
     A list of symbols describing available features of the Guile
     process.

   You shouldn't modify the ‘*features*’ variable directly using ‘set!’.
Instead, see the procedures that are provided for this purpose in the
following subsection.

* Menu:

* Feature Manipulation::        Checking for and advertising features.
* Common Feature Symbols::      Commonly available features.


File: guile.info,  Node: Feature Manipulation,  Next: Common Feature Symbols,  Up: Feature Tracking

5.18.2.1 Feature Manipulation
.............................

To check whether a particular feature is available, use the ‘provided?’
procedure:

 -- Scheme Procedure: provided? feature
 -- Deprecated Scheme Procedure: feature? feature
     Return ‘#t’ if the specified FEATURE is available, otherwise ‘#f’.

   To advertise a feature from your own Scheme code, you can use the
‘provide’ procedure:

 -- Scheme Procedure: provide feature
     Add FEATURE to the list of available features in this Guile
     process.

   For C code, the equivalent function takes its feature name as a ‘char
*’ argument for convenience:

 -- C Function: void scm_add_feature (const char *str)
     Add a symbol with name STR to the list of available features in
     this Guile process.


File: guile.info,  Node: Common Feature Symbols,  Prev: Feature Manipulation,  Up: Feature Tracking

5.18.2.2 Common Feature Symbols
...............................

In general, a particular feature may be available for one of two
reasons.  Either because the Guile library was configured and compiled
with that feature enabled -- i.e.  the feature is built into the library
on your system.  Or because some C or Scheme code that was dynamically
loaded by Guile has added that feature to the list.

   In the first category, here are the features that the current version
of Guile may define (depending on how it is built), and what they mean.

‘array’
     Indicates support for arrays (*note Arrays::).

‘array-for-each’
     Indicates availability of ‘array-for-each’ and other array mapping
     procedures (*note Arrays::).

‘char-ready?’
     Indicates that the ‘char-ready?’ function is available (*note
     Reading::).

‘complex’
     Indicates support for complex numbers.

‘current-time’
     Indicates availability of time-related functions: ‘times’,
     ‘get-internal-run-time’ and so on (*note Time::).

‘debug-extensions’
     Indicates that the debugging evaluator is available, together with
     the options for controlling it.

‘delay’
     Indicates support for promises (*note Delayed Evaluation::).

‘EIDs’
     Indicates that the ‘geteuid’ and ‘getegid’ really return effective
     user and group IDs (*note Processes::).

‘inexact’
     Indicates support for inexact numbers.

‘i/o-extensions’
     Indicates availability of the following extended I/O procedures:
     ‘ftell’, ‘redirect-port’, ‘dup->fdes’, ‘dup2’, ‘fileno’, ‘isatty?’,
     ‘fdopen’, ‘primitive-move->fdes’ and ‘fdes->ports’ (*note Ports and
     File Descriptors::).

‘net-db’
     Indicates availability of network database functions:
     ‘scm_gethost’, ‘scm_getnet’, ‘scm_getproto’, ‘scm_getserv’,
     ‘scm_sethost’, ‘scm_setnet’, ‘scm_setproto’, ‘scm_setserv’, and
     their 'byXXX' variants (*note Network Databases::).

‘posix’
     Indicates support for POSIX functions: ‘pipe’, ‘getgroups’, ‘kill’,
     ‘execl’ and so on (*note POSIX::).

‘random’
     Indicates availability of random number generation functions:
     ‘random’, ‘copy-random-state’, ‘random-uniform’ and so on (*note
     Random::).

‘reckless’
     Indicates that Guile was built with important checks omitted -- you
     should never see this!

‘regex’
     Indicates support for POSIX regular expressions using
     ‘make-regexp’, ‘regexp-exec’ and friends (*note Regexp
     Functions::).

‘socket’
     Indicates availability of socket-related functions: ‘socket’,
     ‘bind’, ‘connect’ and so on (*note Network Sockets and
     Communication::).

‘sort’
     Indicates availability of sorting and merging functions (*note
     Sorting::).

‘system’
     Indicates that the ‘system’ function is available (*note
     Processes::).

‘threads’
     Indicates support for multithreading (*note Threads::).

‘values’
     Indicates support for multiple return values using ‘values’ and
     ‘call-with-values’ (*note Multiple Values::).

   Available features in the second category depend, by definition, on
what additional code your Guile process has loaded in.  The following
table lists features that you might encounter for this reason.

‘defmacro’
     Indicates that the ‘defmacro’ macro is available (*note Macros::).

‘describe’
     Indicates that the ‘(oop goops describe)’ module has been loaded,
     which provides a procedure for describing the contents of GOOPS
     instances.

‘readline’
     Indicates that Guile has loaded in Readline support, for command
     line editing (*note Readline Support::).

‘record’
     Indicates support for record definition using ‘make-record-type’
     and friends (*note Records::).

   Although these tables may seem exhaustive, it is probably unwise in
practice to rely on them, as the correspondences between feature symbols
and available procedures/behaviour are not strictly defined.  If you are
writing code that needs to check for the existence of some procedure, it
is probably safer to do so directly using the ‘defined?’ procedure than
to test for the corresponding feature using ‘provided?’.


File: guile.info,  Node: Runtime Options,  Prev: Feature Tracking,  Up: Options and Config

5.18.3 Runtime Options
----------------------

Guile's runtime behaviour can be modified by setting options.  For
example, is the language that Guile accepts case sensitive, or should
the debugger automatically show a backtrace on error?

   Guile has two levels of interface for managing options: a low-level
control interface, and a user-level interface which allows the enabling
or disabling of options.

   Moreover, the options are classified in groups according to whether
they configure _reading_, _printing_, _debugging_ or _evaluating_.

* Menu:

* Low level options interfaces::
* User level options interfaces::
* Reader options::
* Printing options::
* Debugger options::
* Evaluator options::
* Evaluator trap options::
* Examples of option use::


File: guile.info,  Node: Low level options interfaces,  Next: User level options interfaces,  Up: Runtime Options

5.18.3.1 Low Level Options Interfaces
.....................................

 -- Scheme Procedure: read-options-interface [setting]
 -- Scheme Procedure: eval-options-interface [setting]
 -- Scheme Procedure: print-options-interface [setting]
 -- Scheme Procedure: debug-options-interface [setting]
 -- Scheme Procedure: evaluator-traps-interface [setting]
 -- C Function: scm_read_options (setting)
 -- C Function: scm_eval_options_interface (setting)
 -- C Function: scm_print_options (setting)
 -- C Function: scm_debug_options (setting)
 -- C Function: scm_evaluator_traps (setting)
     If one of these procedures is called with no arguments (or with
     ‘setting == SCM_UNDEFINED’ in C code), it returns a list describing
     the current setting of the read, eval, print, debug or evaluator
     traps options respectively.  The setting of a boolean option is
     indicated simply by the presence or absence of the option symbol in
     the list.  The setting of a non-boolean option is indicated by the
     presence of the option symbol immediately followed by the option's
     current value.

     If called with a list argument, these procedures interpret the list
     as an option setting and modify the relevant options accordingly.
     [FIXME -- this glosses over a lot of details!]

     If called with any other argument, such as ‘'help’, these
     procedures return a list of entries like ‘(OPTION-SYMBOL
     DEFAULT-VALUE DOC-STRING)’, with each entry giving the default
     value and documentation for each option symbol in the relevant set
     of options.


File: guile.info,  Node: User level options interfaces,  Next: Reader options,  Prev: Low level options interfaces,  Up: Runtime Options

5.18.3.2 User Level Options Interfaces
......................................

 -- Scheme Procedure: <group>-options [arg]
 -- Scheme Procedure: read-options [arg]
 -- Scheme Procedure: print-options [arg]
 -- Scheme Procedure: debug-options [arg]
 -- Scheme Procedure: traps [arg]
     These functions list the options in their group.  The optional
     argument ARG is a symbol which modifies the form in which the
     options are presented.

     With no arguments, ‘<group>-options’ returns the values of the
     options in that particular group.  If ARG is ‘'help’, a description
     of each option is given.  If ARG is ‘'full’, programmers' options
     are also shown.

     ARG can also be a list representing the state of all options.  In
     this case, the list contains single symbols (for enabled boolean
     options) and symbols followed by values.
   [FIXME: I don't think 'full is ever any different from 'help.  What's
up?]

 -- Scheme Procedure: <group>-enable option-symbol
 -- Scheme Procedure: read-enable option-symbol
 -- Scheme Procedure: print-enable option-symbol
 -- Scheme Procedure: debug-enable option-symbol
 -- Scheme Procedure: trap-enable option-symbol
     These functions set the specified OPTION-SYMBOL in their options
     group.  They only work if the option is boolean, and throw an error
     otherwise.

 -- Scheme Procedure: <group>-disable option-symbol
 -- Scheme Procedure: read-disable option-symbol
 -- Scheme Procedure: print-disable option-symbol
 -- Scheme Procedure: debug-disable option-symbol
 -- Scheme Procedure: trap-disable option-symbol
     These functions turn off the specified OPTION-SYMBOL in their
     options group.  They only work if the option is boolean, and throw
     an error otherwise.

 -- syntax: <group>-set! option-symbol value
 -- syntax: read-set! option-symbol value
 -- syntax: print-set! option-symbol value
 -- syntax: debug-set! option-symbol value
 -- syntax: trap-set! option-symbol value
     These functions set a non-boolean OPTION-SYMBOL to the specified
     VALUE.


File: guile.info,  Node: Reader options,  Next: Printing options,  Prev: User level options interfaces,  Up: Runtime Options

5.18.3.3 Reader options
.......................

Here is the list of reader options generated by typing ‘(read-options
'full)’ in Guile.  You can also see the default values.

     keywords         #f      Style of keyword recognition: #f, 'prefix or 'postfix
     case-insensitive no      Convert symbols to lower case.
     positions        yes     Record positions of source code expressions.
     copy             no      Copy source code expressions.

   Notice that while Standard Scheme is case insensitive, to ease
translation of other Lisp dialects, notably Emacs Lisp, into Guile,
Guile is case-sensitive by default.

   To make Guile case insensitive, you can type

     (read-enable 'case-insensitive)


File: guile.info,  Node: Printing options,  Next: Evaluator options,  Prev: Reader options,  Up: Runtime Options

5.18.3.4 Printing options
.........................

Here is the list of print options generated by typing ‘(print-options
'full)’ in Guile.  You can also see the default values.

     quote-keywordish-symbols reader How to print symbols that have a colon
                                     as their first or last character. The
                                     value '#f' does not quote the colons;
                                     '#t' quotes them; 'reader' quotes
                                     them when the reader option
                                     'keywords' is not '#f'.

     highlight-prefix         {      The string to print before highlighted values.
     highlight-suffix         }      The string to print after highlighted values.

     source                   no     Print closures with source.
     closure-hook             #f     Hook for printing closures.


File: guile.info,  Node: Evaluator options,  Next: Evaluator trap options,  Prev: Printing options,  Up: Runtime Options

5.18.3.5 Evaluator options
..........................

These are the evaluator options with their default values, as they are
printed by typing ‘(eval-options 'full)’ in Guile.

     stack           22000   Size of thread stacks (in machine words).


File: guile.info,  Node: Evaluator trap options,  Next: Debugger options,  Prev: Evaluator options,  Up: Runtime Options

5.18.3.6 Evaluator trap options
...............................

[FIXME: These flags, together with their corresponding handlers, are not
user level options.  Probably this entire section should be moved to the
documentation about the low-level programmer debugging interface.]

   Here is the list of evaluator trap options generated by typing
‘(traps 'full)’ in Guile.  You can also see the default values.

     exit-frame      no      Trap when exiting eval or apply.
     apply-frame     no      Trap when entering apply.
     enter-frame     no      Trap when eval enters new frame.
     traps		yes	Enable evaluator traps.

 -- apply-frame-handler: key cont tailp
     Called when a procedure is being applied.

     Called if:

        • evaluator traps are enabled [traps interface], and
        • either
             − ‘apply-frame’ is enabled [traps interface], or
             − trace mode is on [debug-options interface], and the
               procedure being called has the trace property enabled.

     CONT is a "debug object", which means that it can be passed to
     ‘make-stack’ to discover the stack at the point of the trap.  The
     apply frame handler's code can capture a restartable continuation
     if it wants to by using ‘call-with-current-continuation’ in the
     usual way.

     TAILP is true if this is a tail call

 -- exit-frame-handler: key cont retval
     Called when a value is returned from a procedure.

     Called if:

        • evaluator traps are enabled [traps interface], and
        • either
             − ‘exit-frame’ is enabled [traps interface], or
             − trace mode is on [debug-options interface], and the
               procedure being called has the trace property enabled.

     CONT is a "debug object", which means that it can be passed to
     ‘make-stack’ to discover the stack at the point of the trap.  The
     exit frame handler's code can capture a restartable continuation if
     it wants to by using ‘call-with-current-continuation’ in the usual
     way.

     RETVAL is the return value.

 -- Scheme Procedure: with-traps thunk
 -- C Function: scm_with_traps (thunk)
     Call THUNK with traps enabled.

 -- Scheme Procedure: debug-object? obj
 -- C Function: scm_debug_object_p (obj)
     Return ‘#t’ if OBJ is a debug object.


File: guile.info,  Node: Debugger options,  Next: Examples of option use,  Prev: Evaluator trap options,  Up: Runtime Options

5.18.3.7 Debugger options
.........................

Here is the list of print options generated by typing ‘(debug-options
'full)’ in Guile.  You can also see the default values.

     stack           20000   Stack size limit (0 = no check).
     debug           yes     Use the debugging evaluator.
     backtrace       no      Show backtrace on error.
     depth           20      Maximal length of printed backtrace.
     maxdepth        1000    Maximal number of stored backtrace frames.
     frames          3       Maximum number of tail-recursive frames in backtrace.
     indent          10      Maximal indentation in backtrace.
     backwards       no      Display backtrace in anti-chronological order.
     procnames       yes     Record procedure names at definition.
     trace           no      *Trace mode.
     breakpoints     no      *Check for breakpoints.
     cheap           yes     *This option is now obsolete.  Setting it has no effect.

Stack overflow
..............

Stack overflow errors are caused by a computation trying to use more
stack space than has been enabled by the ‘stack’ option.  They are
reported like this:

     (non-tail-recursive-factorial 500)
     ⊣
     ERROR: Stack overflow
     ABORT: (stack-overflow)

   If you get an error like this, you can either try rewriting your code
to use less stack space, or increase the maximum stack size.  To
increase the maximum stack size, use ‘debug-set!’, for example:

     (debug-set! stack 200000)
     ⇒
     (show-file-name #t stack 200000 debug backtrace depth 20 maxdepth 1000 frames 3 indent 10 width 79 procnames cheap)

     (non-tail-recursive-factorial 500)
     ⇒
     122013682599111006870123878542304692625357434...

   If you prefer to try rewriting your code, you may be able to save
stack space by making some of your procedures “tail recursive” (*note
Tail Calls::).


File: guile.info,  Node: Examples of option use,  Prev: Debugger options,  Up: Runtime Options

5.18.3.8 Examples of option use
...............................

Here is an example of a session in which some read and debug option
handling procedures are used.  In this example, the user

  1. Notices that the symbols ‘abc’ and ‘aBc’ are not the same
  2. Examines the ‘read-options’, and sees that ‘case-insensitive’ is
     set to "no".
  3. Enables ‘case-insensitive’
  4. Verifies that now ‘aBc’ and ‘abc’ are the same
  5. Disables ‘case-insensitive’ and enables debugging ‘backtrace’
  6. Reproduces the error of displaying ‘aBc’ with backtracing enabled
     [FIXME: this last example is lame because there is no depth in the
     backtrace.  Need to give a better example, possibly putting
     debugging option examples in a separate session.]

     guile> (define abc "hello")
     guile> abc
     "hello"
     guile> aBc
     ERROR: In expression aBc:
     ERROR: Unbound variable: aBc
     ABORT: (misc-error)

     Type "(backtrace)" to get more information.
     guile> (read-options 'help)
     keywords	#f	Style of keyword recognition: #f, 'prefix or 'postfix
     case-insensitive	no	Convert symbols to lower case.
     positions	yes	Record positions of source code expressions.
     copy		no	Copy source code expressions.
     guile> (debug-options 'help)
     stack		20000	Stack size limit (0 = no check).
     debug		yes	Use the debugging evaluator.
     backtrace	no	Show backtrace on error.
     depth		20	Maximal length of printed backtrace.
     maxdepth	1000	Maximal number of stored backtrace frames.
     frames		3	Maximum number of tail-recursive frames in backtrace.
     indent		10	Maximal indentation in backtrace.
     backwards	no	Display backtrace in anti-chronological order.
     procnames	yes	Record procedure names at definition.
     trace		no	*Trace mode.
     breakpoints	no	*Check for breakpoints.
     cheap		yes	*This option is now obsolete.  Setting it has no effect.
     guile> (read-enable 'case-insensitive)
     (keywords #f case-insensitive positions)
     guile> aBc
     "hello"
     guile> (read-disable 'case-insensitive)
     (keywords #f positions)
     guile> (debug-enable 'backtrace)
     (stack 20000 debug backtrace depth 20 maxdepth 1000 frames 3 indent 10 procnames cheap)
     guile> aBc

     Backtrace:
     0* aBc

     ERROR: In expression aBc:
     ERROR: Unbound variable: aBc
     ABORT: (misc-error)
     guile>


File: guile.info,  Node: Translation,  Next: Internationalization,  Prev: Options and Config,  Up: API Reference

5.19 Support for Translating Other Languages
============================================

[Describe translation framework.]

* Menu:

* Emacs Lisp Support::          Helper primitives for Emacs Lisp.


File: guile.info,  Node: Emacs Lisp Support,  Up: Translation

5.19.1 Emacs Lisp Support
-------------------------

 -- Scheme Procedure: nil-car x
 -- C Function: scm_nil_car (x)
     Return the car of X, but convert it to LISP nil if it is Scheme's
     end-of-list.

 -- Scheme Procedure: nil-cdr x
 -- C Function: scm_nil_cdr (x)
     Return the cdr of X, but convert it to LISP nil if it is Scheme's
     end-of-list.

 -- Scheme Procedure: nil-cons x y
 -- C Function: scm_nil_cons (x, y)
     Create a new cons cell with X as the car and Y as the cdr, but
     convert Y to Scheme's end-of-list if it is a Lisp nil.

 -- Scheme Procedure: nil-eq x y
     Compare X and Y and return Lisp's t if they are ‘eq?’, return
     Lisp's nil otherwise.

 -- Scheme Procedure: null x
 -- C Function: scm_null (x)
     Return Lisp's ‘t’ if X is nil in the LISP sense, return Lisp's nil
     otherwise.


File: guile.info,  Node: Internationalization,  Next: Debugging,  Prev: Translation,  Up: API Reference

5.20 Support for Internationalization
=====================================

Guile provides an interface to GNU ‘gettext’ for translating message
strings (*note (gettext)Introduction::).

   Messages are collected in domains, so different libraries and
programs maintain different message catalogues.  The DOMAIN parameter in
the functions below is a string (it becomes part of the message catalog
filename).

   When ‘gettext’ is not available, or if Guile was configured
‘--without-nls’, dummy functions doing no translation are provided.

 -- Scheme Procedure: gettext msg [domain [category]]
 -- C Function: scm_gettext (msg, domain, category)
     Return the translation of MSG in DOMAIN.  DOMAIN is optional and
     defaults to the domain set through ‘textdomain’ below.  CATEGORY is
     optional and defaults to ‘LC_MESSAGES’ (*note Locales::).

     Normal usage is for MSG to be a literal string.  ‘xgettext’ can
     extract those from the source to form a message catalogue ready for
     translators (*note Invoking the ‘xgettext’ Program:
     (gettext)xgettext Invocation.).

          (display (gettext "You are in a maze of twisty passages."))

     ‘_’ is a commonly used shorthand, an application can make that an
     alias for ‘gettext’.  Or a library can make a definition that uses
     its specific DOMAIN (so an application can change the default
     without affecting the library).

          (define (_ msg) (gettext msg "mylibrary"))
          (display (_ "File not found."))

     ‘_’ is also a good place to perhaps strip disambiguating extra text
     from the message string, as for instance in *note How to use
     ‘gettext’ in GUI programs: (gettext)GUI program problems.

 -- Scheme Procedure: ngettext msg msgplural n [domain [category]]
 -- C Function: scm_ngettext (msg, msgplural, n, domain, category)
     Return the translation of MSG/MSGPLURAL in DOMAIN, with a plural
     form chosen appropriately for the number N.  DOMAIN is optional and
     defaults to the domain set through ‘textdomain’ below.  CATEGORY is
     optional and defaults to ‘LC_MESSAGES’ (*note Locales::).

     MSG is the singular form, and MSGPLURAL the plural.  When no
     translation is available, MSG is used if N = 1, or MSGPLURAL
     otherwise.  When translated, the message catalogue can have a
     different rule, and can have more than two possible forms.

     As per ‘gettext’ above, normal usage is for MSG and MSGPLURAL to be
     literal strings, since ‘xgettext’ can extract them from the source
     to build a message catalogue.  For example,

          (define (done n)
            (format #t (ngettext "~a file processed\n"
                                 "~a files processed\n" n)
                       n))

          (done 1) ⊣ 1 file processed
          (done 3) ⊣ 3 files processed

     It's important to use ‘ngettext’ rather than plain ‘gettext’ for
     plurals, since the rules for singular and plural forms in English
     are not the same in other languages.  Only ‘ngettext’ will allow
     translators to give correct forms (*note Additional functions for
     plural forms: (gettext)Plural forms.).

 -- Scheme Procedure: textdomain [domain]
 -- C Function: scm_textdomain (domain)
     Get or set the default gettext domain.  When called with no
     parameter the current domain is returned.  When called with a
     parameter, DOMAIN is set as the current domain, and that new value
     returned.  For example,

          (textdomain "myprog")
          ⇒ "myprog"

 -- Scheme Procedure: bindtextdomain domain [directory]
 -- C Function: scm_bindtextdomain (domain, directory)
     Get or set the directory under which to find message files for
     DOMAIN.  When called without a DIRECTORY the current setting is
     returned.  When called with a DIRECTORY, DIRECTORY is set for
     DOMAIN and that new setting returned.  For example,

          (bindtextdomain "myprog" "/my/tree/share/locale")
          ⇒ "/my/tree/share/locale"

     When using Autoconf/Automake, an application should arrange for the
     configured ‘localedir’ to get into the program (by substituting, or
     by generating a config file) and set that for its domain.  This
     ensures the catalogue can be found even when installed in a
     non-standard location.

 -- Scheme Procedure: bind-textdomain-codeset domain [encoding]
 -- C Function: scm_bind_textdomain_codeset (domain, encoding)
     Get or set the text encoding to be used by ‘gettext’ for messages
     from DOMAIN.  ENCODING is a string, the name of a coding system,
     for instance "8859_1".  (On a Unix/POSIX system the ‘iconv’ program
     can list all available encodings.)

     When called without an ENCODING the current setting is returned, or
     ‘#f’ if none yet set.  When called with an ENCODING, it is set for
     DOMAIN and that new setting returned.  For example,

          (bind-textdomain-codeset "myprog")
          ⇒ #f
          (bind-textdomain-codeset "myprog" "latin-9")
          ⇒ "latin-9"

     The encoding requested can be different from the translated data
     file, messages will be recoded as necessary.  But note that when
     there is no translation, ‘gettext’ returns its MSG unchanged, ie.
     without any recoding.  For that reason source message strings are
     best as plain ASCII.

     Currently Guile has no understanding of multi-byte characters, and
     string functions won't recognise character boundaries in multi-byte
     strings.  An application will at least be able to pass such strings
     through to some output though.  Perhaps this will change in the
     future.


File: guile.info,  Node: Debugging,  Next: GH,  Prev: Internationalization,  Up: API Reference

5.21 Debugging Infrastructure
=============================

In order to understand Guile's debugging facilities, you first need to
understand a little about how the evaluator works and what the Scheme
stack is.  With that in place we explain the low level trap calls that
the evaluator can be configured to make, and the trap and breakpoint
infrastructure that builds on top of those calls.

* Menu:

* Evaluation Model::            Evaluation and the Scheme stack.
* Debug on Error::              Debugging when an error occurs.
* Traps::
* Debugging Examples::


File: guile.info,  Node: Evaluation Model,  Next: Debug on Error,  Up: Debugging

5.21.1 Evaluation and the Scheme Stack
--------------------------------------

The idea of the Scheme stack is central to a lot of debugging.  It
always exists implicitly, as a result of the way that the Guile
evaluator works, and can be summoned into concrete existence as a
first-class Scheme value by the ‘make-stack’ call, so that an
introspective Scheme program - such as a debugger - can present it in
some way and allow the user to query its details.  The first thing to
understand, therefore, is how the workings of the evaluator build up the
stack.

   Broadly speaking, the evaluator performs “evaluations” and
“applications”.  An evaluation means that it is looking at a source code
expression like ‘(+ x 5)’ or ‘(if msg (loop))’, deciding whether the top
level of the expression is a procedure call, macro, builtin syntax, or
whatever, and doing some appropriate processing in each case.  (In the
examples here, ‘(+ x 5)’ would normally be a procedure call, and ‘(if
msg (loop))’ builtin syntax.)  For a procedure call, "appropriate
processing" includes evaluating the procedure's arguments, as that must
happen before the procedure itself can be called.  An application means
calling a procedure once its arguments have been calculated.

   Typically evaluations and applications alternate with each other, and
together they form a “stack” of operations pending completion.  This is
because, on the one hand, evaluation of an expression like ‘(+ x 5)’
requires -- once its arguments have been calculated -- an application
(in this case, of the procedure ‘+’) before it can complete and return a
result, and, on the other hand, the application of a procedure written
in Scheme involves evaluating the sequence of expressions that
constitute that procedure's code.  Each level on this stack is called a
“frame”.

   Therefore, when an error occurs in a running program, or the program
hits a breakpoint, or in fact at any point that the programmer chooses,
its state at that point can be represented by a “stack” of all the
evaluations and procedure applications that are logically in progress at
that time, each of which is known as a “frame”.  The programmer can
learn more about the program's state at that point by inspecting the
stack and its frames.

* Menu:

* Capturing the Stack or Innermost Stack Frame::
* Examining the Stack::
* Examining Stack Frames::
* Source Properties::           Remembering the source of an expression.
* Decoding Memoized Source Expressions::
* Starting a New Stack::


File: guile.info,  Node: Capturing the Stack or Innermost Stack Frame,  Next: Examining the Stack,  Up: Evaluation Model

5.21.1.1 Capturing the Stack or Innermost Stack Frame
.....................................................

A Scheme program can use the ‘make-stack’ primitive anywhere in its
code, with first arg ‘#t’, to construct a Scheme value that describes
the Scheme stack at that point.

     (make-stack #t)
     ⇒
     #<stack 805c840:808d250>

 -- Scheme Procedure: make-stack obj . args
 -- C Function: scm_make_stack (obj, args)
     Create a new stack.  If OBJ is ‘#t’, the current evaluation stack
     is used for creating the stack frames, otherwise the frames are
     taken from OBJ (which must be either a debug object or a
     continuation).

     ARGS should be a list containing any combination of integer,
     procedure and ‘#t’ values.

     These values specify various ways of cutting away uninteresting
     stack frames from the top and bottom of the stack that ‘make-stack’
     returns.  They come in pairs like this: ‘(INNER_CUT_1 OUTER_CUT_1
     INNER_CUT_2 OUTER_CUT_2 ...)’.

     Each INNER_CUT_N can be ‘#t’, an integer, or a procedure.  ‘#t’
     means to cut away all frames up to but excluding the first user
     module frame.  An integer means to cut away exactly that number of
     frames.  A procedure means to cut away all frames up to but
     excluding the application frame whose procedure matches the
     specified one.

     Each OUTER_CUT_N can be an integer or a procedure.  An integer
     means to cut away that number of frames.  A procedure means to cut
     away frames down to but excluding the application frame whose
     procedure matches the specified one.

     If the OUTER_CUT_N of the last pair is missing, it is taken as 0.

 -- Scheme Procedure: last-stack-frame obj
 -- C Function: scm_last_stack_frame (obj)
     Return the last (innermost) frame of OBJ, which must be either a
     debug object or a continuation.


File: guile.info,  Node: Examining the Stack,  Next: Examining Stack Frames,  Prev: Capturing the Stack or Innermost Stack Frame,  Up: Evaluation Model

5.21.1.2 Examining the Stack
............................

 -- Scheme Procedure: stack? obj
 -- C Function: scm_stack_p (obj)
     Return ‘#t’ if OBJ is a calling stack.

 -- Scheme Procedure: stack-id stack
 -- C Function: scm_stack_id (stack)
     Return the identifier given to STACK by ‘start-stack’.

 -- Scheme Procedure: stack-length stack
 -- C Function: scm_stack_length (stack)
     Return the length of STACK.

 -- Scheme Procedure: stack-ref stack index
 -- C Function: scm_stack_ref (stack, index)
     Return the INDEX'th frame from STACK.

 -- Scheme Procedure: display-backtrace stack port [first [depth
          [highlights]]]
 -- C Function: scm_display_backtrace_with_highlights (stack, port,
          first, depth, highlights)
 -- C Function: scm_display_backtrace (stack, port, first, depth)
     Display a backtrace to the output port PORT.  STACK is the stack to
     take the backtrace from, FIRST specifies where in the stack to
     start and DEPTH how many frames to display.  FIRST and DEPTH can be
     ‘#f’, which means that default values will be used.  If HIGHLIGHTS
     is given it should be a list; the elements of this list will be
     highlighted wherever they appear in the backtrace.


File: guile.info,  Node: Examining Stack Frames,  Next: Source Properties,  Prev: Examining the Stack,  Up: Evaluation Model

5.21.1.3 Examining Stack Frames
...............................

 -- Scheme Procedure: frame? obj
 -- C Function: scm_frame_p (obj)
     Return ‘#t’ if OBJ is a stack frame.

 -- Scheme Procedure: frame-number frame
 -- C Function: scm_frame_number (frame)
     Return the frame number of FRAME.

 -- Scheme Procedure: frame-previous frame
 -- C Function: scm_frame_previous (frame)
     Return the previous frame of FRAME, or ‘#f’ if FRAME is the first
     frame in its stack.

 -- Scheme Procedure: frame-next frame
 -- C Function: scm_frame_next (frame)
     Return the next frame of FRAME, or ‘#f’ if FRAME is the last frame
     in its stack.

 -- Scheme Procedure: frame-source frame
 -- C Function: scm_frame_source (frame)
     Return the source of FRAME.

 -- Scheme Procedure: frame-procedure? frame
 -- C Function: scm_frame_procedure_p (frame)
     Return ‘#t’ if a procedure is associated with FRAME.

 -- Scheme Procedure: frame-procedure frame
 -- C Function: scm_frame_procedure (frame)
     Return the procedure for FRAME, or ‘#f’ if no procedure is
     associated with FRAME.

 -- Scheme Procedure: frame-arguments frame
 -- C Function: scm_frame_arguments (frame)
     Return the arguments of FRAME.

 -- Scheme Procedure: frame-evaluating-args? frame
 -- C Function: scm_frame_evaluating_args_p (frame)
     Return ‘#t’ if FRAME contains evaluated arguments.

 -- Scheme Procedure: frame-overflow? frame
 -- C Function: scm_frame_overflow_p (frame)
     Return ‘#t’ if FRAME is an overflow frame.

 -- Scheme Procedure: frame-real? frame
 -- C Function: scm_frame_real_p (frame)
     Return ‘#t’ if FRAME is a real frame.

 -- Scheme Procedure: display-application frame [port [indent]]
 -- C Function: scm_display_application (frame, port, indent)
     Display a procedure application FRAME to the output port PORT.
     INDENT specifies the indentation of the output.


File: guile.info,  Node: Source Properties,  Next: Decoding Memoized Source Expressions,  Prev: Examining Stack Frames,  Up: Evaluation Model

5.21.1.4 Source Properties
..........................

As Guile reads in Scheme code from file or from standard input, it
remembers the file name, line number and column number where each
expression begins.  These pieces of information are known as the “source
properties” of the expression.  If an expression undergoes
transformation -- for example, if there is a syntax transformer in
effect, or the expression is a macro call -- the source properties are
copied from the untransformed to the transformed expression so that, if
an error occurs when evaluating the transformed expression, Guile's
debugger can point back to the file and location where the expression
originated.

   The way that source properties are stored means that Guile can only
associate source properties with parenthesized expressions, and not, for
example, with individual symbols, numbers or strings.  The difference
can be seen by typing ‘(xxx)’ and ‘xxx’ at the Guile prompt (where the
variable ‘xxx’ has not been defined):

     guile> (xxx)
     standard input:2:1: In expression (xxx):
     standard input:2:1: Unbound variable: xxx
     ABORT: (unbound-variable)
     guile> xxx
     <unnamed port>: In expression xxx:
     <unnamed port>: Unbound variable: xxx
     ABORT: (unbound-variable)

In the latter case, no source properties were stored, so the best that
Guile could say regarding the location of the problem was "<unnamed
port>".

   The recording of source properties is controlled by the read option
named "positions" (*note Reader options::).  This option is switched
_on_ by default, together with the debug options "debug" and "backtrace"
(*note Debugger options::), when Guile is run interactively; all these
options are _off_ by default when Guile runs a script non-interactively.

   The following procedures can be used to access and set the source
properties of read expressions.

 -- Scheme Procedure: set-source-properties! obj plist
 -- C Function: scm_set_source_properties_x (obj, plist)
     Install the association list PLIST as the source property list for
     OBJ.

 -- Scheme Procedure: set-source-property! obj key datum
 -- C Function: scm_set_source_property_x (obj, key, datum)
     Set the source property of object OBJ, which is specified by KEY to
     DATUM.  Normally, the key will be a symbol.

 -- Scheme Procedure: source-properties obj
 -- C Function: scm_source_properties (obj)
     Return the source property association list of OBJ.

 -- Scheme Procedure: source-property obj key
 -- C Function: scm_source_property (obj, key)
     Return the source property specified by KEY from OBJ's source
     property list.

   In practice there are only two ways that you should use the ability
to set an expression's source breakpoints.

   • To set a breakpoint on an expression, use ‘(set-source-property!
     EXPR 'breakpoint #t)’.  If you do this, you should also set the
     ‘traps’ and ‘enter-frame-handler’ trap options (*note Evaluator
     trap options::) and ‘breakpoints’ debug option (*note Debugger
     options::) appropriately, and the evaluator will then call your
     enter frame handler whenever it is about to evaluate that
     expression.

   • To make a read or constructed expression appear to have come from a
     different source than what the expression's source properties
     already say, you can use ‘set-source-property!’ to set the
     expression's ‘filename’, ‘line’ and ‘column’ properties.  The
     properties that you set will then show up later if that expression
     is involved in a backtrace or error report.

   If you are looking for a way to attach arbitrary information to an
expression other than these properties, you should use
‘make-object-property’ instead (*note Object Properties::), because that
will avoid bloating the source property hash table, which is really only
intended for the specific purposes described in this section.


File: guile.info,  Node: Decoding Memoized Source Expressions,  Next: Starting a New Stack,  Prev: Source Properties,  Up: Evaluation Model

5.21.1.5 Decoding Memoized Source Expressions
.............................................

 -- Scheme Procedure: memoized? obj
 -- C Function: scm_memoized_p (obj)
     Return ‘#t’ if OBJ is memoized.

 -- Scheme Procedure: unmemoize m
 -- C Function: scm_unmemoize (m)
     Unmemoize the memoized expression M,

 -- Scheme Procedure: memoized-environment m
 -- C Function: scm_memoized_environment (m)
     Return the environment of the memoized expression M.


File: guile.info,  Node: Starting a New Stack,  Prev: Decoding Memoized Source Expressions,  Up: Evaluation Model

5.21.1.6 Starting a New Stack
.............................

 -- Scheme Syntax: start-stack id exp
     Evaluate EXP on a new calling stack with identity ID.  If EXP is
     interrupted during evaluation, backtraces will not display frames
     farther back than EXP's top-level form.  This macro is a way of
     artificially limiting backtraces and stack procedures, largely as a
     convenience to the user.


File: guile.info,  Node: Debug on Error,  Next: Traps,  Prev: Evaluation Model,  Up: Debugging

5.21.2 Debugging when an error occurs
-------------------------------------

A common requirement is to be able to show as much useful context as
possible when a Scheme program hits an error.  The most immediate
information about an error is the kind of error that it is - such as
"division by zero" - and any parameters that the code which signalled
the error chose explicitly to provide.  This information originates with
the ‘error’ or ‘throw’ call (or their C code equivalents, if the error
is detected by C code) that signals the error, and is passed
automatically to the handler procedure of the innermost applicable
‘catch’, ‘lazy-catch’ or ‘with-throw-handler’ expression.

5.21.2.1 Intercepting basic error information
.............................................

Therefore, to catch errors that occur within a chunk of Scheme code, and
to intercept basic information about those errors, you need to execute
that code inside the dynamic context of a ‘catch’, ‘lazy-catch’ or
‘with-throw-handler’ expression, or the equivalent in C. In Scheme, this
means you need something like this:

     (catch #t
            (lambda ()
              ;; Execute the code in which
              ;; you want to catch errors here.
              ...)
            (lambda (key . parameters)
              ;; Put the code which you want
              ;; to handle an error here.
              ...))

The ‘catch’ here can also be ‘lazy-catch’ or ‘with-throw-handler’; see
*note Throw Handlers:: and *note Lazy Catch:: for the details of how
these differ from ‘catch’.  The ‘#t’ means that the catch is applicable
to all kinds of error; if you want to restrict your catch to just one
kind of error, you can put the symbol for that kind of error instead of
‘#t’.  The equivalent to this in C would be something like this:

     SCM my_body_proc (void *body_data)
     {
       /* Execute the code in which
          you want to catch errors here. */
       ...
     }

     SCM my_handler_proc (void *handler_data,
                          SCM key,
                          SCM parameters)
     {
       /* Put the code which you want
          to handle an error here. */
       ...
     }

     {
       ...
       scm_c_catch (SCM_BOOL_T,
                    my_body_proc, body_data,
                    my_handler_proc, handler_data,
                    NULL, NULL);
       ...
     }

Again, as with the Scheme version, ‘scm_c_catch’ could be replaced by
‘scm_internal_lazy_catch’ or ‘scm_c_with_throw_handler’, and
‘SCM_BOOL_T’ could instead be the symbol for a particular kind of error.

5.21.2.2 Capturing the full error stack
.......................................

The other interesting information about an error is the full Scheme
stack at the point where the error occurred; in other words what
innermost expression was being evaluated, what was the expression that
called that one, and so on.  If you want to write your code so that it
captures and can display this information as well, there are three
important things to understand.

   Firstly, the code in question must be executed using the debugging
version of the evaluator, because information about the Scheme stack is
only available at all from the debugging evaluator.  Using the debugging
evaluator means that the debugger option (*note Debugger options::)
called ‘debug’ must be enabled; this can be done by running
‘(debug-enable 'debug)’ or ‘(turn-on-debugging)’ at the top level of
your program; or by running guile with the ‘--debug’ command line
option, if your program begins life as a Scheme script.

   Secondly, the stack at the point of the error needs to be explicitly
captured by a ‘make-stack’ call (or the C equivalent ‘scm_make_stack’).
The Guile library does not do this "automatically" for you, so you will
need to write code with a ‘make-stack’ or ‘scm_make_stack’ call
yourself.  (We emphasise this point because some people are misled by
the fact that the Guile interactive REPL code _does_ capture and display
the stack automatically.  But the Guile interactive REPL is itself a
Scheme program(1) running on top of the Guile library, and which uses
‘catch’ and ‘make-stack’ in the way we are about to describe to capture
the stack when an error occurs.)

   Thirdly, in order to capture the stack effectively at the point where
the error occurred, the ‘make-stack’ call must be made before Guile
unwinds the stack back to the location of the prevailing catch
expression.  This means that the ‘make-stack’ call must be made within
the handler of a ‘lazy-catch’ or ‘with-throw-handler’ expression, or the
optional "pre-unwind" handler of a ‘catch’.  (For the full story of how
these alternatives differ from each other, see *note Exceptions::.  The
main difference is that ‘catch’ terminates the error, whereas
‘lazy-catch’ and ‘with-throw-handler’ only intercept it temporarily and
then allow it to continue propagating up to the next innermost handler.)

   So, here are some examples of how to do all this in Scheme and in C.
For the purpose of these examples we assume that the captured stack
should be stored in a variable, so that it can be displayed or
arbitrarily processed later on.  In Scheme:

     (let ((captured-stack #f))
       (catch #t
              (lambda ()
                ;; Execute the code in which
                ;; you want to catch errors here.
                ...)
              (lambda (key . parameters)
                ;; Put the code which you want
                ;; to handle an error after the
                ;; stack has been unwound here.
                ...)
              (lambda (key . parameters)
                ;; Capture the stack here:
                (set! captured-stack (make-stack #t))))
       ...
       (if captured-stack
           (begin
             ;; Display or process the captured stack.
             ...))
       ...)

And in C:

     SCM my_body_proc (void *body_data)
     {
       /* Execute the code in which
          you want to catch errors here. */
       ...
     }

     SCM my_handler_proc (void *handler_data,
                          SCM key,
                          SCM parameters)
     {
       /* Put the code which you want
          to handle an error after the
          stack has been unwound here. */
       ...
     }

     SCM my_preunwind_proc (void *handler_data,
                            SCM key,
                            SCM parameters)
     {
       /* Capture the stack here: */
       *(SCM *)handler_data = scm_make_stack (SCM_BOOL_T, SCM_EOL);
     }

     {
       SCM captured_stack = SCM_BOOL_F;
       ...
       scm_c_catch (SCM_BOOL_T,
                    my_body_proc, body_data,
                    my_handler_proc, handler_data,
                    my_preunwind_proc, &captured_stack);
       ...
       if (captured_stack != SCM_BOOL_F)
       {
         /* Display or process the captured stack. */
         ...
       }
       ...
     }

Note that you don't have to wait until after the ‘catch’ or
‘scm_c_catch’ has returned.  You can also do whatever you like with the
stack immediately after it has been captured in the pre-unwind handler,
or in the normal (post-unwind) handler.  (Except that for the latter
case in C you will need to change ‘handler_data’ in the
‘scm_c_catch(...)’ call to ‘&captured_stack’, so that ‘my_handler_proc’
has access to the captured stack.)

5.21.2.3 Displaying or interrogating the captured stack
.......................................................

Once you have a captured stack, you can interrogate and display its
details in any way that you want, using the ‘stack-...’ and ‘frame-...’
API described in *note Examining the Stack:: and *note Examining Stack
Frames::.

   If you want to print out a backtrace in the same format that the
Guile REPL does, you can use the ‘display-backtrace’ procedure to do so.
You can also use ‘display-application’ to display an individual
application frame - that is, a frame that satisfies the
‘frame-procedure?’ predicate - in the Guile REPL format.

5.21.2.4 What the Guile REPL does
.................................

The Guile REPL code (in ‘ice-9/boot-9.scm’) uses a ‘catch’ with a
pre-unwind handler to capture the stack when an error occurs in an
expression that was typed into the REPL, and saves the captured stack in
a fluid (*note Fluids and Dynamic States::) called ‘the-last-stack’.
You can then use the ‘(backtrace)’ command, which is basically
equivalent to ‘(display-backtrace (fluid-ref the-last-stack))’, to print
out this stack at any time until it is overwritten by the next error
that occurs.

 -- Scheme Procedure: backtrace [highlights]
 -- C Function: scm_backtrace_with_highlights (highlights)
 -- C Function: scm_backtrace ()
     Display a backtrace of the stack saved by the last error to the
     current output port.  If HIGHLIGHTS is given it should be a list;
     the elements of this list will be highlighted wherever they appear
     in the backtrace.

   You can also use the ‘(debug)’ command to explore the saved stack
using an interactive command-line-driven debugger.  See *note
Interactive Debugger:: for more information about this.

 -- Scheme Procedure: debug
     Invoke the Guile debugger to explore the context of the last error.

   ---------- Footnotes ----------

   (1) In effect, it is the default program which is run when no
commands or script file are specified on the Guile command line.


File: guile.info,  Node: Traps,  Next: Debugging Examples,  Prev: Debug on Error,  Up: Debugging

5.21.3 Traps
------------

The low level C code of Guile's evaluator can be configured to call out
at key points to arbitrary user-specified procedures.  These procedures,
and the circumstances under which the evaluator calls them, are
configured by the "evaluator trap options" interface (*note Evaluator
trap options::), and by the ‘trace’ and ‘breakpoints’ fields of the
"debug options" interface (*note Debugger options::).  In principle this
allows Scheme code to implement any model it chooses for examining the
evaluation stack as program execution proceeds, and for suspending
execution to be resumed later.  Possible applications of this feature
include breakpoints, runtime tracing, code coverage, and profiling.

   Based on these low level trap calls, Guile provides a higher level,
object-oriented interface for the manipulation of traps.  Different
kinds of trap are represented as GOOPS classes; for example, the
‘<procedure-trap>’ class describes traps that are triggered by
invocation of a specified procedure.  A particular instance of a trap
class -- or “trap object” -- describes the condition under which a
single trap will be triggered, and what will happen then; for example,
an instance of ‘<procedure-trap>’ whose ‘procedure’ and ‘behaviour’
slots contain ‘my-factorial’ and ‘debug-trap’ would be a trap that
enters the command line debugger when the ‘my-factorial’ procedure is
invoked.

   The following subsections describe all this in detail, for both the
user wanting to use traps, and the developer interested in understanding
how the interface hangs together.

* Menu:

* How to Set a Trap::
* Specifying Trap Behaviour::
* Trap Context::
* Tracing Examples::
* Tracing Configuration::
* Tracing and (ice-9 debug)::
* Traps Installing More Traps::
* Common Trap Options::
* Procedure Traps::
* Exit Traps::
* Entry Traps::
* Apply Traps::
* Step Traps::
* Source Traps::
* Location Traps::
* Trap Shorthands::
* Trap Utilities::

5.21.3.1 A Quick Note on Terminology
....................................

It feels natural to use the word "trap" in some form for all levels of
the structure just described, so we need to be clear on the terminology
we use to describe each particular level.  The terminology used in this
subsection is as follows.

   • "Low level trap calls", or "low level traps", are the calls made
     directly from the C code of the Guile evaluator.

   • "Trap classes" are self-explanatory.

   • "Trap objects", "trap instances", or just "traps", are instances of
     a trap class, and each describe a single logical trap condition
     plus behaviour as specified by the user of this interface.

   A good example of when it is important to be clear, is when we talk
below of behaviours that should only happen once per low level trap.  A
single low level trap call will typically map onto the processing of
several trap objects, so "once per low level trap" is significantly
different from "once per trap".

* Menu:

* How to Set a Trap::
* Specifying Trap Behaviour::
* Trap Context::
* Tracing Examples::
* Tracing Configuration::
* Tracing and (ice-9 debug)::
* Traps Installing More Traps::
* Common Trap Options::
* Procedure Traps::
* Exit Traps::
* Entry Traps::
* Apply Traps::
* Step Traps::
* Source Traps::
* Location Traps::
* Trap Shorthands::
* Trap Utilities::


File: guile.info,  Node: How to Set a Trap,  Next: Specifying Trap Behaviour,  Up: Traps

5.21.3.2 How to Set a Trap
..........................

Setting a trap is done in two parts.  First the trap is defined by
creating an instance of the appropriate trap class, with slot values
specifying the condition under which the trap will fire and the action
to take when it fires.  Secondly the trap object thus created must be
“installed”.

   To make this immediately concrete, here is an example that sets a
trap to fire on the next application of the ‘facti’ procedure, and to
handle the trap by entering the command line debugger.

     (install-trap (make <procedure-trap>
                     #:procedure facti
                     #:single-shot #t
                     #:behaviour debug-trap))

Briefly, the elements of this incantation are as follows.  (All of these
are described more fully in the following subsubsections.)

   • ‘<procedure-trap>’ is the trap class for trapping on invocation of
     a specific procedure.

   • ‘#:procedure facti’ says that the specific procedure to trap on for
     this trap object is ‘facti’.

   • ‘#:single-shot #t’ says that this trap should only fire on the
     _next_ invocation of ‘facti’, not on all future invocations (which
     is the default if the ‘#:single-shot’ option is not specified).

   • ‘#:behaviour debug-trap’ says that the trap infrastructure should
     call the procedure ‘debug-trap’ when this trap fires.

   • Finally, the ‘install-trap’ call installs the trap immediately.

It is of course possible for the user to define more convenient
shorthands for setting common kinds of traps.  *Note Trap Shorthands::,
for some examples.

   The ability to install, uninstall and reinstall a trap without losing
its definition is Guile's equivalent of the disable/enable commands
provided by debuggers like GDB.

 -- Generic Function: install-trap trap
     Install the trap object TRAP, so that its behaviour will be
     executed when the conditions for the trap firing are met.

 -- Generic Function: uninstall-trap trap
     Uninstall the trap object TRAP, so that its behaviour will _not_ be
     executed even if the conditions for the trap firing are met.


File: guile.info,  Node: Specifying Trap Behaviour,  Next: Trap Context,  Prev: How to Set a Trap,  Up: Traps

5.21.3.3 Specifying Trap Behaviour
..................................

Guile provides several "out-of-the-box" behaviours for common needs.
All of the following can be used directly as the value of the
‘#:behaviour’ option when creating a trap object.

 -- Procedure: debug-trap trap-context
     Enter Guile's command line debugger to explore the stack at
     TRAP-CONTEXT, and to single-step or continue program execution from
     that point.

 -- Procedure: gds-debug-trap trap-context
     Use the GDS debugging interface, which displays the stack and
     corresponding source code via Emacs, to explore the stack at
     TRAP-CONTEXT and to single-step or continue program execution from
     that point.

 -- Procedure: trace-trap trap-context
     Display trace information to summarize the current TRAP-CONTEXT.

 -- Procedure: trace-at-exit trap-context
     Install a further trap to cause the return value of the application
     or evaluation just starting (as described by TRAP-CONTEXT) to be
     traced using ‘trace-trap’, when this application or evaluation
     completes.  The extra trap is automatically uninstalled after the
     return value has been traced.

 -- Procedure: trace-until-exit trap-context
     Install a further trap so that every step that the evaluator
     performs as part of the application or evaluation just starting (as
     described by TRAP-CONTEXT) is traced using ‘trace-trap’.  The extra
     trap is automatically uninstalled when the application or
     evaluation is complete.  ‘trace-until-exit’ can be very useful as a
     first step when all you know is that there is a bug "somewhere in
     XXX or in something that XXX calls".

‘debug-trap’ and ‘gds-debug-trap’ are provided by the modules ‘(ice-9
debugger)’ and ‘(ice-9 gds-client)’ respectively, and their behaviours
are fairly self-explanatory.  For more information on the operation of
the GDS interface via Emacs, see *note Using Guile in Emacs::.  The
tracing behaviours are explained more fully below.

   More generally, the “behaviour” specified for a trap can be any
procedure that expects to be called with one “trap context” argument.  A
trivial example would be:

     (define (report-stack-depth trap-context)
       (display "Stack depth at the trap is: ")
       (display (tc:depth trap-context))
       (newline))


File: guile.info,  Node: Trap Context,  Next: Tracing Examples,  Prev: Specifying Trap Behaviour,  Up: Traps

5.21.3.4 Trap Context
.....................

The “trap context” is an object that caches information about the low
level trap call and the stack at the point of the trap, and is passed as
the only argument to all behaviour procedures.  The information in the
trap context can be accessed through the procedures beginning ‘tc:’ that
are exported by the ‘(ice-9 debugging traps)’ module(1); the most useful
of these are as follows.

 -- Generic Function: tc:type trap-context
     Indicates the type of the low level trap by returning one of the
     keywords ‘#:application’, ‘#:evaluation’, ‘#:return’ or ‘#:error’.

 -- Generic Function: tc:return-value trap-context
     When ‘tc:type’ gives ‘#:return’, this provides the value that is
     being returned.

 -- Generic Function: tc:stack trap-context
     Provides the stack at the point of the trap (as computed by
     ‘make-stack’, but cached so that the lengthy ‘make-stack’ operation
     is not performed more than once for the same low level trap).

 -- Generic Function: tc:frame trap-context
     The innermost frame of the stack at the point of the trap.

 -- Generic Function: tc:depth trap-context
     The number of frames (including tail recursive non-real frames) in
     the stack at the point of the trap.

 -- Generic Function: tc:real-depth trap-context
     The number of real frames (that is, excluding the non-real frames
     that describe tail recursive calls) in the stack at the point of
     the trap.

   ---------- Footnotes ----------

   (1) Plus of course any procedures that build on these, such as the
‘trace/...’ procedures exported by ‘(ice-9 debugging trace)’ (*note
Tracing Configuration::).


File: guile.info,  Node: Tracing Examples,  Next: Tracing Configuration,  Prev: Trap Context,  Up: Traps

5.21.3.5 Tracing Examples
.........................

The following examples show what tracing is and the kind of output that
it generates.  In the first example, we define a recursive function for
reversing a list, then watch the effect of the recursive calls by
tracing each call and return value.

     guile> (define (rev ls)
              (if (null? ls)
                  ls
                  (append (rev (cdr ls))
                          (list (car ls)))))
     guile> (use-modules (ice-9 debugging traps) (ice-9 debugging trace))
     guile> (define t1 (make <procedure-trap>
                         #:procedure rev
                         #:behaviour (list trace-trap
                                           trace-at-exit)))
     guile> (install-trap t1)
     guile> (rev '(a b c))
     |  2: [rev (a b c)]
     |  3: [rev (b c)]
     |  4: [rev (c)]
     |  5: [rev ()]
     |  5: =>()
     |  4: =>(c)
     |  3: =>(c b)
     |  2: =>(c b a)
     (c b a)

The number before the colon in this output (which follows ‘(ice-9
debugging trace)’'s default output format) is the number of real frames
on the stack.  The fact that this number increases for each recursive
call confirms that the implementation above of ‘rev’ is not
tail-recursive.

   In the next example, we probe the _internal_ workings of ‘rev’ in
more detail by using the ‘trace-until-exit’ behaviour.

     guile> (uninstall-trap t1)
     guile> (define t2 (make <procedure-trap>
                         #:procedure rev
                         #:behaviour (list trace-trap
                                           trace-until-exit)))
     guile> (install-trap t2)
     guile> (rev '(a b))
     |  2: [rev (a b)]
     |  2: (if (null? ls) ls (append (rev (cdr ls)) (list (car ls))))
     |  3: (null? ls)
     |  3: [null? (a b)]
     |  3: =>#f
     |  2: (append (rev (cdr ls)) (list (car ls)))
     |  3: (rev (cdr ls))
     |  4: (cdr ls)
     |  4: [cdr (a b)]
     |  4: =>(b)
     |  3: [rev (b)]
     |  3: (if (null? ls) ls (append (rev (cdr ls)) (list (car ls))))
     |  4: (null? ls)
     |  4: [null? (b)]
     |  4: =>#f
     |  3: (append (rev (cdr ls)) (list (car ls)))
     |  4: (rev (cdr ls))
     |  5: (cdr ls)
     |  5: [cdr (b)]
     |  5: =>()
     |  4: [rev ()]
     |  4: (if (null? ls) ls (append (rev (cdr ls)) (list (car ls))))
     |  5: (null? ls)
     |  5: [null? ()]
     |  5: =>#t
     |  4: (list (car ls))
     |  5: (car ls)
     |  5: [car (b)]
     |  5: =>b
     |  4: [list b]
     |  4: =>(b)
     |  3: [append () (b)]
     |  3: =>(b)
     |  3: (list (car ls))
     |  4: (car ls)
     |  4: [car (a b)]
     |  4: =>a
     |  3: [list a]
     |  3: =>(a)
     |  2: [append (b) (a)]
     |  2: =>(b a)
     (b a)

The output in this case shows every step that the evaluator performs in
evaluating ‘(rev '(a b))’.


File: guile.info,  Node: Tracing Configuration,  Next: Tracing and (ice-9 debug),  Prev: Tracing Examples,  Up: Traps

5.21.3.6 Tracing Configuration
..............................

The detail of what gets printed in each trace line, and the port to
which tracing is written, can be configured by the procedures
‘set-trace-layout’ and ‘trace-port’, both exported by the ‘(ice-9
debugging trace)’ module.

 -- Procedure with Setter: trace-port
     Get or set the port to which tracing is printed.  The default is
     the value of ‘(current-output-port)’ when the ‘(ice-9 debugging
     trace)’ module is first loaded.

 -- Procedure: set-trace-layout format-string . arg-procs
     Layout each trace line using FORMAT-STRING and ARG-PROCS.  For each
     trace line, the list of values to be printed is obtained by calling
     all the ARG-PROCS, passing the trap context as the only parameter
     to each one.  This list of values is then formatted using the
     specified FORMAT-STRING.

The ‘(ice-9 debugging trace)’ module exports a set of arg-proc
procedures to cover most common needs, with names beginning ‘trace/’.
These are all implemented on top of the ‘tc:’ trap context accessor
procedures documented in *note Trap Context::, and if any trace output
not provided by the following is needed, it should be possible to
implement based on a combination of the ‘tc:’ procedures.

 -- Procedure: trace/pid trap-context
     An arg-proc that returns the current process ID.

 -- Procedure: trace/stack-id trap-context
     An arg-proc that returns the stack ID of the stack in which the
     current trap occurred.

 -- Procedure: trace/stack-depth trap-context
     An arg-proc that returns the length (including non-real frames) of
     the stack at the point of the current trap.

 -- Procedure: trace/stack-real-depth trap-context
     An arg-proc that returns the length excluding non-real frames of
     the stack at the point of the current trap.

 -- Procedure: trace/stack trap-context
     An arg-proc that returns a string summarizing stack information.
     This string includes the stack ID, real depth, and count of
     additional non-real frames, with the format ‘"~a:~a+~a"’.

 -- Procedure: trace/source-file-name trap-context
     An arg-proc that returns the name of the source file for the
     innermost stack frame, or an empty string if source is not
     available for the innermost frame.

 -- Procedure: trace/source-line trap-context
     An arg-proc that returns the line number of the source code for the
     innermost stack frame, or zero if source is not available for the
     innermost frame.

 -- Procedure: trace/source-column trap-context
     An arg-proc that returns the column number of the start of the
     source code for the innermost stack frame, or zero if source is not
     available for the innermost frame.

 -- Procedure: trace/source trap-context
     An arg-proc that returns the source location for the innermost
     stack frame.  This is a string composed of file name, line and
     column number with the format ‘"~a:~a:~a"’, or an empty string if
     source is not available for the innermost frame.

 -- Procedure: trace/type trap-context
     An arg-proc that returns a three letter abbreviation indicating the
     type of the current trap: ‘"APP"’ for an application frame, ‘"EVA"’
     for an evaluation, ‘"RET"’ for an exit trap, or ‘"ERR"’ for an
     error (pseudo-)trap.

 -- Procedure: trace/real? trap-context
     An arg-proc that returns ‘" "’ if the innermost stack frame is a
     real frame, or ‘"t"’ if it is not.

 -- Procedure: trace/info trap-context
     An arg-proc that returns a string describing the expression being
     evaluated, application being performed, or return value, according
     to the current trap type.

‘trace/stack-depth’ and ‘trace/stack-real-depth’ are identical to the
trap context methods ‘tc:depth’ and ‘tc:real-depth’ described before
(*note Trap Context::), but renamed here for convenience.

   The default trace layout, as exhibited by the examples of the
previous subsubsubsection, is set by this line of code from the ‘(ice-9
debugging traps)’ module:

     (set-trace-layout "|~3@a: ~a\n" trace/stack-real-depth trace/info)

If we rerun the first of those examples, but with trace layout
configured to show source location and trap type in addition, the output
looks like this:

     guile> (set-trace-layout "| ~25a ~3@a: ~a ~a\n"
                              trace/source
                              trace/stack-real-depth
                              trace/type
                              trace/info)
     guile> (rev '(a b c))
     | standard input:29:0         2: APP [rev (a b c)]
     | standard input:4:21         3: APP [rev (b c)]
     | standard input:4:21         4: APP [rev (c)]
     | standard input:4:21         5: APP [rev ()]
     | standard input:2:9          5: RET =>()
     | standard input:4:13         4: RET =>(c)
     | standard input:4:13         3: RET =>(c b)
     | standard input:4:13         2: RET =>(c b a)
     (c b a)


File: guile.info,  Node: Tracing and (ice-9 debug),  Next: Traps Installing More Traps,  Prev: Tracing Configuration,  Up: Traps

5.21.3.7 Tracing and (ice-9 debug)
..................................

The ‘(ice-9 debug)’ module provides a tracing facility (*note Tracing::)
that is roughly similar to that described here, but there are important
differences.

   • The ‘(ice-9 debug)’ trace gives a nice pictorial view of changes in
     stack depth, by using indentation like this:

          [fact1 4]
          |  [fact1 3]
          |  |  [fact1 2]
          |  |  |  [fact1 1]
          |  |  |  |  [fact1 0]
          |  |  |  |  1
          |  |  |  1
          |  |  2
          |  6
          24

     However its output can _only_ show the information seen here, which
     corresponds to ‘(ice-9 debugging trace)’'s ‘trace/info’ procedure;
     it cannot be configured to show other pieces of information about
     the trap context in the way that the ‘(ice-9 debugging trace)’
     implementation can.

   • The ‘(ice-9 debug)’ trace only allows the tracing of procedure
     applications and their return values, whereas the ‘(ice-9 debugging
     trace)’ implementation allows any kind of trap to be traced.

     It's interesting to note that ‘(ice-9 debug)’'s restriction here,
     which might initially appear to be just a straightforward
     consequence of its implementation, is also somewhat dictated by its
     pictorial display.  The use of indentation in the output relies on
     hooking into the low level trap calls in such a way that the
     trapped application entries and exits exactly balance each other.
     The ‘ice-9 debugging trace’ implementation allows traps to be
     installed such that entry and exit traps don't necessarily balance,
     which means that, in general, indentation diagrams like the one
     above don't work.

   It isn't currently possible to use both ‘(ice-9 debug)’ trace and
‘(ice-9 debugging trace)’ in the same Guile session, because their
settings of the low level trap options conflict with each other.


File: guile.info,  Node: Traps Installing More Traps,  Next: Common Trap Options,  Prev: Tracing and (ice-9 debug),  Up: Traps

5.21.3.8 Traps Installing More Traps
....................................

Sometimes it is desirable for the behaviour at one trap to install
further traps.  In other words, the behaviour is something like "Don't
do much right now, but set things up to stop after two or three more
steps", or "... when this frame completes".  This is absolutely fine.
For example, it is easy to code a generic "do so-and-so when the current
frame exits" procedure, which can be used wherever a trap context is
available, as follows.

     (define (at-exit trap-context behaviour)
       (install-trap (make <exit-trap>
     		  #:depth (tc:depth trap-context)
     		  #:single-shot #t
     		  #:behaviour behaviour)))

   To continue and pin down the example, this could then be used as part
of a behaviour whose purpose was to measure the accumulated time spent
in and below a specified procedure.

     (define calls 0)
     (define total 0)

     (define accumulate-time
       (lambda (trap-context)
         (set! calls (+ calls 1))
         (let ((entry (current-time)))
           (at-exit trap-context
             (lambda (ignored)
               (set! total
                     (+ total (- (current-time)
                                 entry))))))))

     (install-trap (make <procedure-trap>
                     #:procedure my-proc
                     #:behaviour accumulate-time))


File: guile.info,  Node: Common Trap Options,  Next: Procedure Traps,  Prev: Traps Installing More Traps,  Up: Traps

5.21.3.9 Common Trap Options
............................

When creating any kind of trap object, settings for the trap being
created are specified as options on the ‘make’ call using syntax like
this:

     (make <TRAP-CLASS>
       #:OPTION-KEYWORD SETTING
       ...)

   The following common options are provided by the base class ‘<trap>’,
and so can be specified for any kind of trap.

 -- Class: <trap>
     Base class for trap objects.

 -- Trap Option: #:condition thunk
     If not ‘#f’, this is a thunk which is called when the trap fires,
     to determine whether trap processing should proceed any further.
     If the thunk returns ‘#f’, the trap is basically suppressed.
     Otherwise processing continues normally.  (Default value ‘#f’.)

 -- Trap Option: #:skip-count count
     A count of valid (after ‘#:condition’ processing) firings of this
     trap to skip.  (Default value 0.)

 -- Trap Option: #:single-shot boolean
     If not ‘#f’, this indicates that the trap should be automatically
     uninstalled after it has successfully fired (after ‘#:condition’
     and ‘#:skip-count’ processing) for the first time.  (Default value
     ‘#f’.)

 -- Trap Option: #:behaviour behaviour-proc
     A trap behaviour procedure -- as discussed in the preceding
     subsubsection -- or a list of such procedures, in which case each
     procedure is called in turn when the trap fires.  (Default value
     ‘'()’.)

 -- Trap Option: #:repeat-identical-behaviour boolean
     Normally, if multiple trap objects are triggered by the same low
     level trap, and they request the same behaviour, it's only actually
     useful to do that behaviour once (per low level trap); so by
     default multiple requests for the same behaviour are coalesced.  If
     this option is set other than ‘#f’, the contents of the
     ‘#:behaviour’ option are uniquified so that they avoid being
     coalesced in this way.  (Default value ‘#f’.)


File: guile.info,  Node: Procedure Traps,  Next: Exit Traps,  Prev: Common Trap Options,  Up: Traps

5.21.3.10 Procedure Traps
.........................

The ‘<procedure-trap>’ class implements traps that are triggered upon
application of a specified procedure.  Instances of this class should
use the ‘#:procedure’ option to specify the procedure to trap on.

 -- Class: <procedure-trap>
     Class for traps triggered by application of a specified procedure.

 -- Trap Option: #:procedure procedure
     Specifies the procedure to trap on.

Example:

     (install-trap (make <procedure-trap>
                     #:procedure my-proc
                     #:behaviour (list trace-trap
                                       trace-until-exit)))


File: guile.info,  Node: Exit Traps,  Next: Entry Traps,  Prev: Procedure Traps,  Up: Traps

5.21.3.11 Exit Traps
....................

The ‘<exit-trap>’ class implements traps that are triggered upon stack
frame exit past a specified stack depth.  Instances of this class should
use the ‘#:depth’ option to specify the target stack depth.

 -- Class: <exit-trap>
     Class for traps triggered by exit past a specified stack depth.

 -- Trap Option: #:depth depth
     Specifies the reference depth for the trap.

Example:

     (define (trace-at-exit trap-context)
       (install-trap (make <exit-trap>
     		  #:depth (tc:depth trap-context)
     		  #:single-shot #t
     		  #:behaviour trace-trap)))

(This is the actual definition of the ‘trace-at-exit’ behaviour.)


File: guile.info,  Node: Entry Traps,  Next: Apply Traps,  Prev: Exit Traps,  Up: Traps

5.21.3.12 Entry Traps
.....................

The ‘<entry-trap>’ class implements traps that are triggered upon any
stack frame entry.  No further parameters are needed to specify an
instance of this class, so there are no class-specific trap options.
Note that it remains possible to use the common trap options (*note
Common Trap Options::), for example to set a trap for the Nth next frame
entry.

 -- Class: <entry-trap>
     Class for traps triggered by any stack frame entry.

Example:

     (install-trap (make <entry-trap>
             	#:skip-count 5
     		#:behaviour gds-debug-trap))


File: guile.info,  Node: Apply Traps,  Next: Step Traps,  Prev: Entry Traps,  Up: Traps

5.21.3.13 Apply Traps
.....................

The ‘<apply-trap>’ class implements traps that are triggered upon any
procedure application.  No further parameters are needed to specify an
instance of this class, so there are no class-specific trap options.
Note that it remains possible to use the common trap options (*note
Common Trap Options::), for example to set a trap for the next
application where some condition is true.

 -- Class: <apply-trap>
     Class for traps triggered by any procedure application.

Example:

     (install-trap (make <apply-trap>
             	#:condition my-condition
     		#:behaviour gds-debug-trap))


File: guile.info,  Node: Step Traps,  Next: Source Traps,  Prev: Apply Traps,  Up: Traps

5.21.3.14 Step Traps
....................

The ‘<step-trap>’ class implements traps that do single-stepping through
a program's execution.  They come in two flavours, with and without a
specified file name.  If a file name is specified, the trap is triggered
by the next evaluation, application or frame exit pertaining to source
code from the specified file.  If a file name is not specified, the trap
is triggered by the next evaluation, application or frame exit from any
file (or for code whose source location was not recorded), in other
words by the next evaluator step of any kind.

   The design goal of the ‘<step-trap>’ class is to match what a user
would intuitively think of as single-stepping through their code, either
through code in general (roughly corresponding to GDB's ‘step’ command,
for example), or through code from a particular source file (roughly
corresponding to GDB's ‘next’).  Therefore if you are using a step trap
to single-step through code and finding its behaviour counter-intuitive,
please report that so we can improve it.

   The implementation and options of the ‘<step-trap>’ class are
complicated by the fact that it is unreliable to determine whether a low
level frame exit trap is applicable to a specified file by examining the
details of the reported frame.  This is a consequence of tail recursion,
which has the effect that many frames can be removed from the stack at
once, with only the outermost frame being reported by the low level trap
call.  The effects of this on the ‘<step-trap>’ class are such as to
require the introduction of the strange-looking ‘#:exit-depth’ option,
for the following reasons.

   • When stopped at the start of an application or evaluation frame,
     and it is desired to continue execution until the next "step" in
     the same source file, that next step could be the start of a nested
     application or evaluation frame, or -- if the procedure definition
     is in a different file, for example -- it could be the exit from
     the current frame.

   • Because of the effects of tail recursion noted above, the current
     frame exit possibility must be expressed as frame exit past a
     specified stack depth.  When an instance of the ‘<step-trap>’ class
     is installed from the context of an application or evaluation frame
     entry, the ‘#:exit-depth’ option should be used to specify this
     stack depth.

   • When stopped at a frame exit, on the other hand, we know that the
     next step must be an application or evaluation frame entry.  In
     this context the ‘#:exit-depth’ option is not needed and should be
     omitted or set to ‘#f’.

When a step trap is installed without ‘#:single-shot #t’, such that it
keeps firing, the ‘<step-trap>’ code automatically updates its idea of
the ‘#:exit-depth’ setting each time, so that the trap always fires
correctly for the following step.

 -- Class: <step-trap>
     Class for single-stepping traps.

 -- Trap Option: #:file-name name
     If not ‘#f’, this is a string containing the name of a source file,
     and restricts the step trap to evaluation steps within that source
     file.  (Default value ‘#f’.)

 -- Trap Option: #:exit-depth depth
     If not ‘#f’, this is a positive integer implying that the next step
     may be frame exit past the stack depth DEPTH.  See the discussion
     above for more details.  (Default value ‘#f’.)

Example:

     (install-trap (make <step-trap>
                     #:file-name (frame-file-name
                                   (stack-ref stack index))
                     #:exit-depth (- (stack-length stack)
                                     (stack-ref stack index))
                     #:single-shot #t
                     #:behaviour debug-trap))


File: guile.info,  Node: Source Traps,  Next: Location Traps,  Prev: Step Traps,  Up: Traps

5.21.3.15 Source Traps
......................

The ‘<source-trap>’ class implements traps that are attached to a
precise source code expression, as read by the reader, and which fire
each time that that expression is evaluated.  These traps use a low
level Guile feature which can mark individual expressions for trapping,
and are relatively efficient.  But it can be tricky to get at the source
expression in the first place, and these traps are liable to become
irrelevant if the procedure containing the expression is reevaluated;
these issues are discussed further below.

 -- Class: <source-trap>
     Class for traps triggered by evaluation of a specific Scheme
     expression.

 -- Trap Option: #:expression expr
     Specifies the Scheme expression to trap on.

Example:

     (display "Enter an expression: ")
     (let ((x (read)))
       (install-trap (make <source-trap>
                       #:expression x
                       #:behaviour (list trace-trap
                                         trace-at-exit)))
       (primitive-eval x))
     ⊣
     Enter an expression: (+ 1 2 3 4 5 6)
     |  3: (+ 1 2 3 4 5 6)
     |  3: =>21
     21

   The key point here is that the expression specified by the
‘#:expression’ option must be _exactly_ (i.e.  ‘eq?’ to) what is going
to be evaluated later.  It doesn't work, for example, to say
‘#:expression '(+ x 3)’, with the expectation that the trap will fire
whenever evaluating any expression ‘(+ x 3)’.

   The ‘trap-here’ macro can be used in source code to create and
install a source trap correctly.  Take for example the factorial
function defined in the ‘(ice-9 debugging example-fns)’ module:

     (define (fact1 n)
       (if (= n 0)
           1
           (* n (fact1 (- n 1)))))

To set a source trap on a particular expression -- let's say the
expression ‘(= n 0)’ -- edit the code so that the expression is enclosed
in a ‘trap-here’ macro call like this:

     (define (fact1 n)
       (if (trap-here (= n 0) #:behaviour debug-trap)
           1
           (* n (fact1 (- n 1)))))

 -- Macro: trap-here expression . trap-options
     Install a source trap with options TRAP-OPTIONS on EXPRESSION, then
     return with the whole call transformed to ‘(begin EXPRESSION)’.

   Note that if the ‘trap-here’ incantation is removed, and ‘fact1’ then
redefined by reloading its source file, the effect of the source trap is
lost, because the text "(= n 0)" is read again from scratch and becomes
a new expression ‘(= n 0)’ which does not have the "trap here" mark on
it.

   If the semantics and setting of source traps seem unwieldy, location
traps may meet your need more closely; these are described in the
following subsubsection.


File: guile.info,  Node: Location Traps,  Next: Trap Shorthands,  Prev: Source Traps,  Up: Traps

5.21.3.16 Location Traps
........................

The ‘<location-trap>’ class implements traps that are triggered by
evaluation of code at a specific source location.  When compared with
source traps, they are easier to set, and do not become irrelevant when
the relevant code is reloaded; but unfortunately they are a lot less
efficient, as they require running some "are we in the right place for a
trap" code on every low level frame entry trap call.

 -- Class: <location-trap>
     Class for traps triggered by evaluation of code at a specific
     source location.

 -- Trap Option: #:file-regexp regexp
     A regular expression specifying the filenames that will match this
     trap.  This option must be specified when creating a location trap.

 -- Trap Option: #:line line
     The line number (0-based) of the source location at which the trap
     should be triggered.  This option must be specified when creating a
     location trap.

 -- Trap Option: #:column column
     The column number (0-based) of the source location at which the
     trap should be triggered.  This option must be specified when
     creating a location trap.

Here is an example, which matches the ‘(facti (- n 1) (* a n))’
expression in ‘ice-9/debugging/example-fns.scm’:

     (install-trap (make <location-trap>
                     #:file-regexp "example-fns.scm"
                     #:line 11
                     #:column 6
                     #:behaviour gds-debug-trap))


File: guile.info,  Node: Trap Shorthands,  Next: Trap Utilities,  Prev: Location Traps,  Up: Traps

5.21.3.17 Trap Shorthands
.........................

If the code described in the preceding subsubsections for creating and
manipulating traps seems a little long-winded, it is of course possible
to define more convenient shorthand forms for typical usage patterns.
Here are some examples.

     (define (break! proc)
       (install-trap (make <procedure-trap>
                       #:procedure proc
                       #:behaviour gds-debug-trap)))

     (define (trace! proc)
       (install-trap (make <procedure-trap>
                       #:procedure proc
                       #:behaviour (list trace-trap
                                         trace-at-exit))))

     (define (trace-subtree! proc)
       (install-trap (make <procedure-trap>
                       #:procedure proc
                       #:behaviour (list trace-trap
                                         trace-until-exit))))

   Definitions like these are not provided out-of-the-box by Guile,
because different users will have different ideas about what their
default debugger should be, or, for example, which of the common trap
options (*note Common Trap Options::) it might be useful to expose
through such shorthand procedures.


File: guile.info,  Node: Trap Utilities,  Prev: Trap Shorthands,  Up: Traps

5.21.3.18 Trap Utilities
........................

‘list-traps’ can be used to print a description of all known trap
objects.  This uses a weak value hash table, keyed by a trap index
number.  Each trap object has its index number assigned, and is added to
the hash table, when it is created by a ‘make TRAP-CLASS ...’ call.
When a trap object is GC'd, it is automatically removed from the hash
table, and so no longer appears in the output from ‘list-traps’.

 -- Variable: all-traps
     Weak value hash table containing all known trap objects.

 -- Procedure: list-traps
     Print a description of all known trap objects.

   The following example shows a single trap that traces applications of
the procedure ‘facti’.

     guile> (list-traps)
     #<<procedure-trap> 100d2e30> is an instance of class <procedure-trap>
     Slots are:
          number = 1
          installed = #t
          condition = #f
          skip-count = 0
          single-shot = #f
          behaviour = (#<procedure trace-trap (trap-context)>)
          repeat-identical-behaviour = #f
          procedure = #<procedure facti (n a)>

   When ‘all-traps’ or ‘list-traps’ reveals a trap that you want to
modify but no longer have a reference to, you can retrieve the trap
object by calling ‘get-trap’ with the trap's number.  For example,
here's how you could change the behaviour of the trap listed just above.

     (slot-set! (get-trap 1) 'behaviour (list debug-trap))

 -- Procedure: get-trap number
     Return the trap object with the specified NUMBER, or ‘#f’ if there
     isn't one.


File: guile.info,  Node: Debugging Examples,  Prev: Traps,  Up: Debugging

5.21.4 Debugging Examples
-------------------------

Here we present some examples of what you can do with the debugging
facilities just described.

* Menu:

* Single Stepping through a Procedure's Code::
* Profiling or Tracing a Procedure's Code::


File: guile.info,  Node: Single Stepping through a Procedure's Code,  Next: Profiling or Tracing a Procedure's Code,  Up: Debugging Examples

5.21.4.1 Single Stepping through a Procedure's Code
...................................................

A good way to explore in detail what a Scheme procedure does is to set a
trap on it and then single step through what it does.  To do this, make
and install a ‘<procedure-trap>’ with the ‘debug-trap’ behaviour from
‘(ice-9 debugging ice-9-debugger-extensions)’.

   The following sample session illustrates this.  It assumes that the
file ‘matrix.scm’ defines a procedure ‘mkmatrix’, which is the one we
want to explore, and another procedure ‘do-main’ which calls ‘mkmatrix’.

     $ /usr/bin/guile -q
     guile> (use-modules (ice-9 debugger)
                         (ice-9 debugging ice-9-debugger-extensions)
                         (ice-9 debugging traps))
     guile> (load "matrix.scm")
     guile> (install-trap (make <procedure-trap>
                            #:procedure mkmatrix
                            #:behaviour debug-trap))
     guile> (do-main 4)
     This is the Guile debugger -- for help, type `help'.
     There are 3 frames on the stack.

     Frame 2 at matrix.scm:8:3
             [mkmatrix]
     debug> next
     Frame 3 at matrix.scm:4:3
             (let ((x 1)) (quote this-is-a-matric))
     debug> info frame
     Stack frame: 3
     This frame is an evaluation.
     The expression being evaluated is:
     matrix.scm:4:3:
       (let ((x 1)) (quote this-is-a-matric))
     debug> next
     Frame 3 at matrix.scm:5:21
             (quote this-is-a-matric)
     debug> bt
     In unknown file:
        ?: 0* [primitive-eval (do-main 4)]
     In standard input:
        4: 1* [do-main 4]
     In matrix.scm:
        8: 2  [mkmatrix]
        ...
        5: 3  (quote this-is-a-matric)
     debug> quit
     this-is-a-matric
     guile>

   Or you can use Guile's Emacs interface (GDS), by using the module
‘(ice-9 gds-client)’ instead of ‘(ice-9 debugger)’ and ‘(ice-9 debugging
ice-9-debugger-extensions)’, and changing ‘debug-trap’ to
‘gds-debug-trap’.  Then the stack and corresponding source locations are
displayed in Emacs instead of on the Guile command line.


File: guile.info,  Node: Profiling or Tracing a Procedure's Code,  Prev: Single Stepping through a Procedure's Code,  Up: Debugging Examples

5.21.4.2 Profiling or Tracing a Procedure's Code
................................................

What if you wanted to get a trace of everything that the Guile evaluator
does within a given procedure, but without Guile stopping and waiting
for your input at every step?  For this requirement you can install a
trap on the procedure, as in the previous example, but instead of
‘debug-trap’ or ‘gds-debug-trap’, use the ‘trace-trap’ and
‘trace-until-exit’ behaviours provided by the ‘(ice-9 debugging trace)’
module.

     guile> (use-modules (ice-9 debugging traps) (ice-9 debugging trace))
     guile> (load "matrix.scm")
     guile> (install-trap (make <procedure-trap>
                            #:procedure mkmatrix
                            #:behaviour (list trace-trap trace-until-exit)))
     guile> (do-main 4)
     |  2: [mkmatrix]
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
     |  4: (and (memq sym bindings) (let ...))
     |  5: (memq sym bindings)
     |  5: [memq define (debug)]
     |  5: =>#f
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
     |  4: (and (memq sym bindings) (let ...))
     |  5: (memq sym bindings)
     |  5: [memq define (debug)]
     |  5: =>#f
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
     |  4: (and (memq sym bindings) (let ...))
     |  5: (memq sym bindings)
     |  5: [memq let (debug)]
     |  5: =>#f
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
     |  4: (and (memq sym bindings) (let ...))
     |  5: (memq sym bindings)
     |  5: [memq let (debug)]
     |  5: =>#f
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
     |  4: (and (memq sym bindings) (let ...))
     |  5: (memq sym bindings)
     |  5: [memq let (debug)]
     |  5: =>#f
     |  2: (letrec ((yy 23)) (let ((x 1)) (quote this-is-a-matric)))
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
     |  4: (and (memq sym bindings) (let ...))
     |  5: (memq sym bindings)
     |  5: [memq let (debug)]
     |  5: =>#f
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
     |  4: (and (memq sym bindings) (let ...))
     |  5: (memq sym bindings)
     |  5: [memq let (debug)]
     |  5: =>#f
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
     |  4: (and (memq sym bindings) (let ...))
     |  5: (memq sym bindings)
     |  5: [memq let (debug)]
     |  5: =>#f
     |  2: (let ((x 1)) (quote this-is-a-matric))
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
     |  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
     |  4: (and (memq sym bindings) (let ...))
     |  5: (memq sym bindings)
     |  5: [memq let (debug)]
     |  5: =>#f
     |  2: [let (let # #) (# # #)]
     |  2: [let (let # #) (# # #)]
     |  2: =>(#@let* (x 1) #@let (quote this-is-a-matric))
     this-is-a-matric
     guile> (do-main 4)
     |  2: [mkmatrix]
     |  2: (letrec ((yy 23)) (let* ((x 1)) (quote this-is-a-matric)))
     |  2: (let* ((x 1)) (quote this-is-a-matric))
     |  2: (quote this-is-a-matric)
     |  2: =>this-is-a-matric
     this-is-a-matric
     guile>

   This example shows the default configuration for how each line of
trace output is formatted, which is:

   • the character ‘|’, a visual clue that the line is a line of trace
     output, followed by

   • a number indicating the real evaluator stack depth (where "real"
     means not counting tail-calls), followed by

   • a summary of the expression being evaluated (‘(...)’), the
     procedure being called (‘[...]’), or the value being returned from
     an evaluation or procedure call (‘=>...’).

You can customize ‘(ice-9 debugging trace)’ to show different
information in each trace line using the ‘set-trace-layout’ procedure.
The next example shows how to get the source location in each trace line
instead of the stack depth.

     guile> (set-trace-layout "|~16@a: ~a\n" trace/source trace/info)
     guile> (do-main 4)
     |  matrix.scm:7:2: [mkmatrix]
     |                : (letrec ((yy 23)) (let* ((x 1)) (quote this-is-a-matric)))
     |  matrix.scm:3:2: (let* ((x 1)) (quote this-is-a-matric))
     |  matrix.scm:4:4: (quote this-is-a-matric)
     |  matrix.scm:4:4: =>this-is-a-matric
     this-is-a-matric
     guile>

   (For anyone wondering why the first ‘(do-main 4)’ call above
generates lots more trace lines than the subsequent calls: these
examples also demonstrate how the Guile evaluator "memoizes" code.  When
Guile evaluates a source code expression for the first time, it changes
some parts of the expression so that they will be quicker to evaluate
when that expression is evaluated again; this is called memoization.
The trace output from the first ‘(do-main 4)’ call shows memoization
steps, such as an internal define being transformed to a letrec.)


File: guile.info,  Node: GH,  Prev: Debugging,  Up: API Reference

5.22 GH: A Portable C to Scheme Interface
=========================================

This chapter shows how to use the GH interface to call Guile from your
application's C code, and to add new Scheme level procedures to Guile
whose behaviour is specified by application specific code written in C.

   Note, however, that the GH interface is now deprecated, and
developers are encouraged to switch to using the scm interface instead.
Therefore, for each GH feature, this chapter also documents how to
achieve the same result using the scm interface.

* Menu:

* GH deprecation::              Why the GH interface is now deprecated.
* Transitioning away from GH::
* GH preliminaries::
* Data types and constants defined by GH::
* Starting and controlling the interpreter::
* Error messages::
* Executing Scheme code::
* Defining new Scheme procedures in C::
* Converting data between C and Scheme::
* Type predicates::
* Equality predicates::
* Memory allocation and garbage collection::
* Calling Scheme procedures from C::


File: guile.info,  Node: GH deprecation,  Next: Transitioning away from GH,  Up: GH

5.22.1 Why the GH Interface is Now Deprecated
---------------------------------------------

Historically, the GH interface was the product of a practical problem
and a neat idea.  The practical problem was that the interface of the
‘scm_’ functions with which Guile itself was written (inherited from
Aubrey Jaffer's SCM) was so closely tied to the (rather arcane) details
of the internal data representation that it was extremely difficult to
write a Guile extension using these functions.  The neat idea was to
define a high level language extension interface in such a way that
other extension language projects, not just Guile, would be able to
provide an implementation of that interface; then applications using
this interface could be compiled with whichever of the various available
implementations they chose.  So the GH interface was created, and
advertised both as the recommended interface for application developers
wishing to use Guile, and as a portable high level interface that could
theoretically be implemented by other extension language projects.

   Time passed, and various things changed.  Crucially, an enormous
number of improvements were made to the ‘scm_’ interface that Guile
itself uses in its implementation, with the result that it is now both
easy and comfortable to write a Guile extension with this interface.  At
the same time, the contents of the GH interface were somewhat neglected
by the core Guile developers, such that some key operations -- such as
smob creation and management -- are simply not possible using GH alone.
Finally, the idea of multiple implementations of the GH interface did
not really crystallize (apart, I believe, from a short lived
implementation by the MzScheme project).

   For all these reasons, the Guile developers have decided to deprecate
the GH interface -- which means that support for GH will be completely
removed after the next few releases -- and to focus only on the ‘scm_’
interface, with additions to ensure that it is as easy to use in all
respects as GH was.

   It remains an open question whether a deep kind of interface
portability would be useful for extension language-based applications,
and it may still be an interesting project to attempt to define a
corresponding GH-like interface, but the Guile developers no longer plan
to try to do this as part of the core Guile project.


File: guile.info,  Node: Transitioning away from GH,  Next: GH preliminaries,  Prev: GH deprecation,  Up: GH

5.22.2 Transitioning away from GH
---------------------------------

The following table summarizes how to transition from the GH to the scm
interface.  The replacements that are recommended are not always
completely equivalent to the GH functionality that they should replace.
Therefore, you should read the reference documentation of the
replacements carefully if you are not yet familiar with them.

Header file
     Use ‘#include <libguile.h>’ instead of ‘#include <guile/gh.h>’.

Compiling and Linking
     Use ‘guile-config’ to pick up the flags required to compile C or
     C++ code that uses ‘libguile’, like so

          $(CC) -o prog.o -c prog.c `guile-config compile`

     If you are using libtool to link your executables, just use
     ‘-lguile’ in your link command.  Libtool will expand this into the
     needed linker options automatically.  If you are not using libtool,
     use the ‘guile-config’ program to query the needed options
     explicitly.  A linker command like

          $(CC) -o prog prog.o `guile-config link`

     should be all that is needed.  To link shared libraries that will
     be used as Guile Extensions, use libtool to control both the
     compilation and the link stage.

The ‘SCM’ type
     No change: the scm interface also uses this type to represent an
     arbitrary Scheme value.

‘SCM_BOOL_F’ and ‘SCM_BOOL_T’
     No change.

‘SCM_UNSPECIFIED’ and ‘SCM_UNDEFINED’
     No change.

‘gh_enter’
     Use ‘scm_boot_guile’ instead, but note that ‘scm_boot_guile’ has a
     slightly different calling convention from ‘gh_enter’:
     ‘scm_boot_guile’, and the main program function that you specify
     for ‘scm_boot_guile’ to call, both take an additional CLOSURE
     parameter.  *note Guile Initialization Functions:: for more
     details.

‘gh_repl’
     Use ‘scm_shell’ instead.

‘gh_init’
     Use ‘scm_init_guile’ instead.

‘gh_catch’
     Use ‘scm_internal_catch’ instead.

‘gh_eval_str’
     Use ‘scm_c_eval_string’ instead.

‘gh_eval_str_with_catch’
     Use ‘scm_c_eval_string’ together with ‘scm_internal_catch’ instead.

‘gh_eval_str_with_standard_handler’
     Use ‘scm_c_eval_string’ together with ‘scm_internal_catch’ and
     ‘scm_handle_by_message_no_exit’ instead.

‘gh_eval_str_with_stack_saving_handler’
     Use ‘scm_c_eval_string’ together with ‘scm_internal_stack_catch’
     and ‘scm_handle_by_message_no_exit’ instead.

‘gh_eval_file’ or ‘gh_load’
     Use ‘scm_c_primitive_load’ instead.

‘gh_eval_file_with_catch’
     Use ‘scm_c_primitive_load’ together with ‘scm_internal_catch’
     instead.

‘gh_eval_file_with_standard_handler’
     Use ‘scm_c_primitive_load’ together with ‘scm_internal_catch’ and
     ‘scm_handle_by_message_no_exit’ instead.

‘gh_new_procedure’
‘gh_new_procedure0_0’
‘gh_new_procedure0_1’
‘gh_new_procedure0_2’
‘gh_new_procedure1_0’
‘gh_new_procedure1_1’
‘gh_new_procedure1_2’
‘gh_new_procedure2_0’
‘gh_new_procedure2_1’
‘gh_new_procedure2_2’
‘gh_new_procedure3_0’
‘gh_new_procedure4_0’
‘gh_new_procedure5_0’
     Use ‘scm_c_define_gsubr’ instead, but note that the arguments are
     in a different order: for ‘scm_c_define_gsubr’ the C function
     pointer is the last argument.  *note A Sample Guile Extension:: for
     an example.

‘gh_defer_ints’ and ‘gh_allow_ints’
     Use ‘SCM_CRITICAL_SECTION_START’ and ‘SCM_CRITICAL_SECTION_END’
     instead.  Note that these macros are used without parentheses, as
     in ‘SCM_DEFER_INTS;’.

‘gh_bool2scm’
     Use ‘scm_from_bool’ instead.

‘gh_int2scm’
     Use ‘scm_from_int’ instead.

‘gh_ulong2scm’
     Use ‘scm_from_ulong’ instead.

‘gh_long2scm’
     Use ‘scm_from_long’ instead.

‘gh_double2scm’
     Use ‘scm_make_real’ instead.

‘gh_char2scm’
     Use ‘SCM_MAKE_CHAR’ instead.

‘gh_str2scm’
     Use ‘scm_from_locale_stringn’ instead.

‘gh_str02scm’
     Use ‘scm_from_locale_string’ instead.

‘gh_set_substr’
     Use ‘scm_string_copy_x’.

‘gh_symbol2scm’
     Use ‘scm_from_locale_symbol’ instead.

‘gh_ints2scm’
‘gh_doubles2scm’
‘gh_chars2byvect’
‘gh_shorts2svect’
‘gh_longs2ivect’
‘gh_ulongs2uvect’
‘gh_floats2fvect’
‘gh_doubles2dvect’
     Use the uniform numeric vector function, *Note Uniform Numeric
     Vectors::.

‘gh_scm2bool’
     Use ‘scm_is_true’ or ‘scm_to_bool’ instead.

‘gh_scm2int’
     Use ‘scm_to_int’ instead.

‘gh_scm2ulong’
     Use ‘scm_to_ulong’ instead.

‘gh_scm2long’
     Use ‘scm_to_long’ instead.

‘gh_scm2double’
     Use ‘scm_to_double’ instead.

‘gh_scm2char’
     Use ‘scm_to_char’ instead.

‘gh_scm2newstr’
     Use ‘scm_to_locale_string’ or similar instead.

‘gh_get_substr’
     Use ‘scm_c_substring’ together with ‘scm_to_locale_string’ or
     similar instead.

‘gh_symbol2newstr’
     Use ‘scm_symbol_to_string’ together with ‘scm_to_locale_string’ or
     similar instead.

‘gh_scm2chars’
     Use ‘scm_from_locale_string’ (or similar) or the uniform numeric
     vector functions (*note Uniform Numeric Vectors::) instead.

‘gh_scm2shorts’
‘gh_scm2longs’
‘gh_scm2floats’
‘gh_scm2doubles’
     Use the uniform numeric vector function, *Note Uniform Numeric
     Vectors::.

‘gh_boolean_p’
     Use ‘scm_is_bool’ instead.

‘gh_symbol_p’
     Use ‘scm_is_symbol’ instead.

‘gh_char_p’
     Replace ‘gh_char_p (OBJ)’ with
          scm_is_true (scm_char_p (OBJ))

‘gh_vector_p’
     Replace ‘gh_vector_p (OBJ)’ with
          scm_is_true (scm_vector_p (OBJ))

‘gh_pair_p’
     Replace ‘gh_pair_p (OBJ)’ with
          scm_is_true (scm_pair_p (OBJ))

‘gh_number_p’
     Use ‘scm_is_number’ instead.

‘gh_string_p’
     Use ‘scm_is_string’ instead.

‘gh_procedure_p’
     Replace ‘gh_procedure_p (OBJ)’ by
          scm_is_true (scm_procedure_p (OBJ))

‘gh_list_p’
     Replace ‘gh_list_p (OBJ)’ with
          scm_is_true (scm_list_p (OBJ))

‘gh_inexact_p’
     Replace ‘gh_inexact_p (OBJ)’ with
          scm_is_true (scm_inexact_p (OBJ))

‘gh_exact_p’
     Replace ‘gh_exact_p (OBJ)’ with
          scm_is_true (scm_exact_p (OBJ))

‘gh_eq_p’
     Use ‘scm_is_eq’ instead.

‘gh_eqv_p’
     Replace ‘gh_eqv_p (X, Y)’ with
          scm_is_true (scm_eqv_p (X, Y))

‘gh_equal_p’
     Replace ‘gh_equal_p (X, Y)’ with
          scm_is_true (scm_equal_p (X, Y))

‘gh_string_equal_p’
     Replace ‘gh_string_equal_p (X, Y)’ with
          scm_is_true (scm_string_equal_p (X, Y))

‘gh_null_p’
     Use ‘scm_is_null’ instead.

‘gh_not’
     Use ‘scm_not’ instead.

‘gh_make_string’
     Use ‘scm_make_string’ instead.

‘gh_string_length’
     Use ‘scm_string_length’ instead.

‘gh_string_ref’
     Use ‘scm_string_ref’ instead.

‘gh_string_set_x’
     Use ‘scm_string_set_x’ instead.

‘gh_substring’
     Use ‘scm_substring’ instead.

‘gh_string_append’
     Use ‘scm_string_append’ instead.

‘gh_cons’
     Use ‘scm_cons’ instead.

‘gh_car’ and ‘gh_cdr’
     Use ‘scm_car’ and ‘scm_cdr’ instead.

‘gh_cxxr’ and ‘gh_cxxxr’
     (Where each x is either ‘a’ or ‘d’.)  Use the corresponding
     ‘scm_cxxr’ or ‘scm_cxxxr’ function instead.

‘gh_set_car_x’ and ‘gh_set_cdr_x’
     Use ‘scm_set_car_x’ and ‘scm_set_cdr_x’ instead.

‘gh_list’
     Use ‘scm_list_n’ instead.

‘gh_length’
     Replace ‘gh_length (LST)’ with
          scm_to_size_t (scm_length (LST))

‘gh_append’
     Use ‘scm_append’ instead.

‘gh_append2’, ‘gh_append3’, ‘gh_append4’
     Replace ‘gh_appendN (L1, ..., LN)’ by
          scm_append (scm_list_n (L1, ..., LN, SCM_UNDEFINED))

‘gh_reverse’
     Use ‘scm_reverse’ instead.

‘gh_list_tail’ and ‘gh_list_ref’
     Use ‘scm_list_tail’ and ‘scm_list_ref’ instead.

‘gh_memq’, ‘gh_memv’ and ‘gh_member’
     Use ‘scm_memq’, ‘scm_memv’ and ‘scm_member’ instead.

‘gh_assq’, ‘gh_assv’ and ‘gh_assoc’
     Use ‘scm_assq’, ‘scm_assv’ and ‘scm_assoc’ instead.

‘gh_make_vector’
     Use ‘scm_make_vector’ instead.

‘gh_vector’ or ‘gh_list_to_vector’
     Use ‘scm_vector’ instead.

‘gh_vector_ref’ and ‘gh_vector_set_x’
     Use ‘scm_vector_ref’ and ‘scm_vector_set_x’ instead.

‘gh_vector_length’
     Use ‘scm_c_vector_length’ instead.

‘gh_uniform_vector_length’
     Use ‘scm_c_uniform_vector_length’ instead.

‘gh_uniform_vector_ref’
     Use ‘scm_c_uniform_vector_ref’ instead.

‘gh_vector_to_list’
     Use ‘scm_vector_to_list’ instead.

‘gh_apply’
     Use ‘scm_apply_0’ instead.

‘gh_call0’
‘gh_call1’
‘gh_call2’
‘gh_call3’
     Use ‘scm_call_0’, ‘scm_call_1’, etc instead.

‘gh_display’
‘gh_write’
‘gh_newline’
     Use ‘scm_display (obj, scm_current_output_port ())’ instead, etc.

‘gh_lookup’
     Use ‘scm_variable_ref (scm_c_lookup (name))’ instead.

‘gh_module_lookup’
     Use ‘scm_variable_ref (scm_c_module_lookup (module, name))’
     instead.


File: guile.info,  Node: GH preliminaries,  Next: Data types and constants defined by GH,  Prev: Transitioning away from GH,  Up: GH

5.22.3 GH preliminaries
-----------------------

To use gh, you must have the following toward the beginning of your C
source:
     #include <guile/gh.h>

   When you link, you will have to add at least ‘-lguile’ to the list of
libraries.  If you are using more of Guile than the basic Scheme
interpreter, you will have to add more libraries.


File: guile.info,  Node: Data types and constants defined by GH,  Next: Starting and controlling the interpreter,  Prev: GH preliminaries,  Up: GH

5.22.4 Data types and constants defined by GH
---------------------------------------------

The following C constants and data types are defined in gh:

   ‘SCM’ is a C data type used to store all Scheme data, no matter what
the Scheme type.  Values are converted between C data types and the SCM
type with utility functions described below (*note Converting data
between C and Scheme::).  [FIXME: put in references to Jim's essay and
so forth.]

 -- Constant: SCM_BOOL_T
 -- Constant: SCM_BOOL_F
     The _Scheme_ values returned by many boolean procedures in
     libguile.

     This can cause confusion because they are different from 0 and 1.
     In testing a boolean function in libguile programming, you must
     always make sure that you check the spec: ‘gh_’ and ‘scm_’
     functions will usually return ‘SCM_BOOL_T’ and ‘SCM_BOOL_F’, but
     other C functions usually can be tested against 0 and 1, so
     programmers' fingers tend to just type ‘if (boolean_function()) {
     ... }’

 -- Constant: SCM_UNSPECIFIED
     This is a SCM value that is not the same as any legal Scheme value.
     It is the value that a Scheme function returns when its
     specification says that its return value is unspecified.

 -- Constant: SCM_UNDEFINED
     This is another SCM value that is not the same as any legal Scheme
     value.  It is the value used to mark variables that do not yet have
     a value, and it is also used in C to terminate functions with
     variable numbers of arguments, such as ‘gh_list()’.


File: guile.info,  Node: Starting and controlling the interpreter,  Next: Error messages,  Prev: Data types and constants defined by GH,  Up: GH

5.22.5 Starting and controlling the interpreter
-----------------------------------------------

In almost every case, your first ‘gh_’ call will be:

 -- Function: void gh_enter (int ARGC, char *ARGV[], void
          (*MAIN_PROG)())
     Starts up a Scheme interpreter with all the builtin Scheme
     primitives.  ‘gh_enter()’ never exits, and the user's code should
     all be in the ‘MAIN_PROG()’ function.  ‘argc’ and ‘argv’ will be
     passed to MAIN_PROG.

      -- Function: void main_prog (int ARGC, char *ARGV[])
          This is the user's main program.  It will be invoked by
          ‘gh_enter()’ after Guile has been started up.

     Note that you can use ‘gh_repl’ inside ‘gh_enter’ (in other words,
     inside the code for ‘main-prog’) if you want the program to be
     controlled by a Scheme read-eval-print loop.

   A convenience routine which enters the Guile interpreter with the
standard Guile read-eval-print loop (“REPL”) is:

 -- Function: void gh_repl (int ARGC, char *ARGV[])
     Enters the Scheme interpreter giving control to the Scheme REPL.
     Arguments are processed as if the Guile program ‘guile’ were being
     invoked.

     Note that ‘gh_repl’ should be used _inside_ ‘gh_enter’, since any
     Guile interpreter calls are meaningless unless they happen in the
     context of the interpreter.

     Also note that when you use ‘gh_repl’, your program will be
     controlled by Guile's REPL (which is written in Scheme and has many
     useful features).  Use straight C code inside ‘gh_enter’ if you
     want to maintain execution control in your C program.

   You will typically use ‘gh_enter’ and ‘gh_repl’ when you want a Guile
interpreter enhanced by your own libraries, but otherwise quite normal.
For example, to build a Guile-derived program that includes some random
number routines “GSL” (GNU Scientific Library), you would write a C
program that looks like this:

     #include <guile/gh.h>
     #include <gsl_ran.h>

     /* random number suite */
     SCM gw_ran_seed(SCM s)
     {
       gsl_ran_seed(gh_scm2int(s));
       return SCM_UNSPECIFIED;
     }

     SCM gw_ran_random()
     {
       SCM x;

       x = gh_ulong2scm(gsl_ran_random());
       return x;
     }

     SCM gw_ran_uniform()
     {
       SCM x;

       x = gh_double2scm(gsl_ran_uniform());
       return x;
     }
     SCM gw_ran_max()
     {
       return gh_double2scm(gsl_ran_max());
     }

     void
     init_gsl()
     {
       /* random number suite */
       gh_new_procedure("gsl-ran-seed", gw_ran_seed, 1, 0, 0);
       gh_new_procedure("gsl-ran-random", gw_ran_random, 0, 0, 0);
       gh_new_procedure("gsl-ran-uniform", gw_ran_uniform, 0, 0, 0);
       gh_new_procedure("gsl-ran-max", gw_ran_max, 0, 0, 0);
     }

     void
     main_prog (int argc, char *argv[])
     {
       init_gsl();

       gh_repl(argc, argv);
     }

     int
     main (int argc, char *argv[])
     {
       gh_enter (argc, argv, main_prog);
     }

   Then, supposing the C program is in ‘guile-gsl.c’, you could compile
it with ‘gcc -o guile-gsl guile-gsl.c -lguile -lgsl’.

   The resulting program ‘guile-gsl’ would have new primitive procedures
‘gsl-ran-random’, ‘gsl-ran-gaussian’ and so forth.


File: guile.info,  Node: Error messages,  Next: Executing Scheme code,  Prev: Starting and controlling the interpreter,  Up: GH

5.22.6 Error messages
---------------------

[FIXME: need to fill this based on Jim's new mechanism]


File: guile.info,  Node: Executing Scheme code,  Next: Defining new Scheme procedures in C,  Prev: Error messages,  Up: GH

5.22.7 Executing Scheme code
----------------------------

Once you have an interpreter running, you can ask it to evaluate Scheme
code.  There are two calls that implement this:

 -- Function: SCM gh_eval_str (char *SCHEME_CODE)
     This asks the interpreter to evaluate a single string of Scheme
     code, and returns the result of the last expression evaluated.

     Note that the line of code in SCHEME_CODE must be a well formed
     Scheme expression.  If you have many lines of code before you
     balance parentheses, you must either concatenate them into one
     string, or use ‘gh_eval_file()’.

 -- Function: SCM gh_eval_file (char *FNAME)
 -- Function: SCM gh_load (char *FNAME)
     ‘gh_eval_file’ is completely analogous to ‘gh_eval_str()’, except
     that a whole file is evaluated instead of a string.  ‘gh_eval_file’
     returns ‘SCM_UNSPECIFIED’.

     ‘gh_load’ is identical to ‘gh_eval_file’ (it's a macro that calls
     ‘gh_eval_file’ on its argument).  It is provided to start making
     the ‘gh_’ interface match the R5RS Scheme procedures closely.


File: guile.info,  Node: Defining new Scheme procedures in C,  Next: Converting data between C and Scheme,  Prev: Executing Scheme code,  Up: GH

5.22.8 Defining new Scheme procedures in C
------------------------------------------

The real interface between C and Scheme comes when you can write new
Scheme procedures in C. This is done through the routine

 -- Libguile high: SCM gh_new_procedure (char *PROC_NAME, SCM (*FN)(),
          int N_REQUIRED_ARGS, int N_OPTIONAL_ARGS, int RESTP)
     ‘gh_new_procedure’ defines a new Scheme procedure.  Its Scheme name
     will be PROC_NAME, it will be implemented by the C function
     (*FN)(), it will take at least N_REQUIRED_ARGS arguments, and at
     most N_OPTIONAL_ARGS extra arguments.

     When the RESTP parameter is 1, the procedure takes a final
     argument: a list of remaining parameters.

     ‘gh_new_procedure’ returns an SCM value representing the procedure.

     The C function FN should have the form
      -- Libguile high: SCM fn (SCM REQ1, SCM REQ2, ..., SCM OPT1, SCM
               OPT2, ..., SCM REST_ARGS)
          The arguments are all passed as SCM values, so the user will
          have to use the conversion functions to convert to standard C
          types.

          Examples of C functions used as new Scheme primitives can be
          found in the sample programs ‘learn0’ and ‘learn1’.

   *Rationale:* this is the correct way to define new Scheme procedures
in C. The ugly mess of arguments is required because of how C handles
procedures with variable numbers of arguments.

   *NB:* what about documentation strings?

   There are several important considerations to be made when writing
the C routine ‘(*fn)()’.

   First of all the C routine has to return type ‘SCM’.

   Second, all arguments passed to the C function will be of type ‘SCM’.

   Third: the C routine is now subject to Scheme flow control, which
means that it could be interrupted at any point, and then reentered.
This means that you have to be very careful with operations such as
allocating memory, modifying static data ...

   Fourth: to get around the latter issue, you can use ‘GH_DEFER_INTS’
and ‘GH_ALLOW_INTS’.

 -- Macro: GH_DEFER_INTS
 -- Macro: GH_ALLOW_INTS
     These macros disable and re-enable Scheme's flow control.  They


File: guile.info,  Node: Converting data between C and Scheme,  Next: Type predicates,  Prev: Defining new Scheme procedures in C,  Up: GH

5.22.9 Converting data between C and Scheme
-------------------------------------------

Guile provides mechanisms to convert data between C and Scheme.  This
allows new builtin procedures to understand their arguments (which are
of type ‘SCM’) and return values of type ‘SCM’.

* Menu:

* C to Scheme::
* Scheme to C::


File: guile.info,  Node: C to Scheme,  Next: Scheme to C,  Up: Converting data between C and Scheme

5.22.9.1 C to Scheme
....................

 -- Function: SCM gh_bool2scm (int X)
     Returns ‘#f’ if X is zero, ‘#t’ otherwise.

 -- Function: SCM gh_ulong2scm (unsigned long X)
 -- Function: SCM gh_long2scm (long X)
 -- Function: SCM gh_double2scm (double X)
 -- Function: SCM gh_char2scm (char X)
     Returns a Scheme object with the value of the C quantity X.

 -- Function: SCM gh_str2scm (char *S, int LEN)
     Returns a new Scheme string with the (not necessarily
     null-terminated) C array S data.

 -- Function: SCM gh_str02scm (char *S)
     Returns a new Scheme string with the null-terminated C string S
     data.

 -- Function: SCM gh_set_substr (char *SRC, SCM DST, int START, int LEN)
     Copy LEN characters at SRC into the _existing_ Scheme string DST,
     starting at START.  START is an index into DST; zero means the
     beginning of the string.

     If START + LEN is off the end of DST, signal an out-of-range error.

 -- Function: SCM gh_symbol2scm (char *NAME)
     Given a null-terminated string NAME, return the symbol with that
     name.

 -- Function: SCM gh_ints2scm (int *DPTR, int N)
 -- Function: SCM gh_doubles2scm (double *DPTR, int N)
     Make a scheme vector containing the N ints or doubles at memory
     location DPTR.

 -- Function: SCM gh_chars2byvect (char *DPTR, int N)
 -- Function: SCM gh_shorts2svect (short *DPTR, int N)
 -- Function: SCM gh_longs2ivect (long *DPTR, int N)
 -- Function: SCM gh_ulongs2uvect (ulong *DPTR, int N)
 -- Function: SCM gh_floats2fvect (float *DPTR, int N)
 -- Function: SCM gh_doubles2dvect (double *DPTR, int N)
     Make a scheme uniform vector containing the N chars, shorts, longs,
     unsigned longs, floats or doubles at memory location DPTR.


File: guile.info,  Node: Scheme to C,  Prev: C to Scheme,  Up: Converting data between C and Scheme

5.22.9.2 Scheme to C
....................

 -- Function: int gh_scm2bool (SCM OBJ)
 -- Function: unsigned long gh_scm2ulong (SCM OBJ)
 -- Function: long gh_scm2long (SCM OBJ)
 -- Function: double gh_scm2double (SCM OBJ)
 -- Function: int gh_scm2char (SCM OBJ)
     These routines convert the Scheme object to the given C type.

 -- Function: char * gh_scm2newstr (SCM STR, size_t *LENP)
     Given a Scheme string STR, return a pointer to a new copy of its
     contents, followed by a null byte.  If LENP is non-null, set
     ‘*LENP’ to the string's length.

     This function uses malloc to obtain storage for the copy; the
     caller is responsible for freeing it.

     Note that Scheme strings may contain arbitrary data, including null
     characters.  This means that null termination is not a reliable way
     to determine the length of the returned value.  However, the
     function always copies the complete contents of STR, and sets *LENP
     to the true length of the string (when LENP is non-null).

 -- Function: void gh_get_substr (SCM str, char *return_str, int *lenp)
     Copy LEN characters at START from the Scheme string SRC to memory
     at DST.  START is an index into SRC; zero means the beginning of
     the string.  DST has already been allocated by the caller.

     If START + LEN is off the end of SRC, signal an out-of-range error.

 -- Function: char * gh_symbol2newstr (SCM SYM, int *LENP)
     Takes a Scheme symbol and returns a string of the form
     ‘"'symbol-name"’.  If LENP is non-null, the string's length is
     returned in ‘*LENP’.

     This function uses malloc to obtain storage for the returned
     string; the caller is responsible for freeing it.

 -- Function: char * gh_scm2chars (SCM VECTOR, chars *RESULT)
 -- Function: short * gh_scm2shorts (SCM VECTOR, short *RESULT)
 -- Function: long * gh_scm2longs (SCM VECTOR, long *RESULT)
 -- Function: float * gh_scm2floats (SCM VECTOR, float *RESULT)
 -- Function: double * gh_scm2doubles (SCM VECTOR, double *RESULT)
     Copy the numbers in VECTOR to the array pointed to by RESULT and
     return it.  If RESULT is NULL, allocate a double array large
     enough.

     VECTOR can be an ordinary vector, a weak vector, or a signed or
     unsigned uniform vector of the same type as the result array.  For
     chars, VECTOR can be a string or substring.  For floats and
     doubles, VECTOR can contain a mix of inexact and integer values.

     If VECTOR is of unsigned type and contains values too large to fit
     in the signed destination array, those values will be wrapped
     around, that is, data will be copied as if the destination array
     was unsigned.


File: guile.info,  Node: Type predicates,  Next: Equality predicates,  Prev: Converting data between C and Scheme,  Up: GH

5.22.10 Type predicates
-----------------------

These C functions mirror Scheme's type predicate procedures with one
important difference.  The C routines return C boolean values (0 and 1)
instead of ‘SCM_BOOL_T’ and ‘SCM_BOOL_F’.

   The Scheme notational convention of putting a ‘?’ at the end of
predicate procedure names is mirrored in C by placing ‘_p’ at the end of
the procedure.  For example, ‘(pair? ...)’ maps to ‘gh_pair_p(...)’.

 -- Function: int gh_boolean_p (SCM VAL)
     Returns 1 if VAL is a boolean, 0 otherwise.

 -- Function: int gh_symbol_p (SCM VAL)
     Returns 1 if VAL is a symbol, 0 otherwise.

 -- Function: int gh_char_p (SCM VAL)
     Returns 1 if VAL is a char, 0 otherwise.

 -- Function: int gh_vector_p (SCM VAL)
     Returns 1 if VAL is a vector, 0 otherwise.

 -- Function: int gh_pair_p (SCM VAL)
     Returns 1 if VAL is a pair, 0 otherwise.

 -- Function: int gh_procedure_p (SCM VAL)
     Returns 1 if VAL is a procedure, 0 otherwise.

 -- Function: int gh_list_p (SCM VAL)
     Returns 1 if VAL is a list, 0 otherwise.

 -- Function: int gh_inexact_p (SCM VAL)
     Returns 1 if VAL is an inexact number, 0 otherwise.

 -- Function: int gh_exact_p (SCM VAL)
     Returns 1 if VAL is an exact number, 0 otherwise.


File: guile.info,  Node: Equality predicates,  Next: Memory allocation and garbage collection,  Prev: Type predicates,  Up: GH

5.22.11 Equality predicates
---------------------------

These C functions mirror Scheme's equality predicate procedures with one
important difference.  The C routines return C boolean values (0 and 1)
instead of ‘SCM_BOOL_T’ and ‘SCM_BOOL_F’.

   The Scheme notational convention of putting a ‘?’ at the end of
predicate procedure names is mirrored in C by placing ‘_p’ at the end of
the procedure.  For example, ‘(equal? ...)’ maps to ‘gh_equal_p(...)’.

 -- Function: int gh_eq_p (SCM x, SCM y)
     Returns 1 if X and Y are equal in the sense of Scheme's ‘eq?’
     predicate, 0 otherwise.

 -- Function: int gh_eqv_p (SCM x, SCM y)
     Returns 1 if X and Y are equal in the sense of Scheme's ‘eqv?’
     predicate, 0 otherwise.

 -- Function: int gh_equal_p (SCM x, SCM y)
     Returns 1 if X and Y are equal in the sense of Scheme's ‘equal?’
     predicate, 0 otherwise.

 -- Function: int gh_string_equal_p (SCM S1, SCM S2)
     Returns 1 if the strings S1 and S2 are equal, 0 otherwise.

 -- Function: int gh_null_p (SCM L)
     Returns 1 if L is an empty list or pair; 0 otherwise.


File: guile.info,  Node: Memory allocation and garbage collection,  Next: Calling Scheme procedures from C,  Prev: Equality predicates,  Up: GH

5.22.12 Memory allocation and garbage collection
------------------------------------------------


File: guile.info,  Node: Calling Scheme procedures from C,  Prev: Memory allocation and garbage collection,  Up: GH

5.22.13 Calling Scheme procedures from C
----------------------------------------

Many of the Scheme primitives are available in the ‘gh_’ interface; they
take and return objects of type SCM, and one could basically use them to
write C code that mimics Scheme code.

   I will list these routines here without much explanation, since what
they do is the same as documented in *note R5RS: (r5rs)Standard
procedures.  But I will point out that when a procedure takes a variable
number of arguments (such as ‘gh_list’), you should pass the constant
SCM_UNDEFINED from C to signify the end of the list.

 -- Function: SCM gh_define (char *NAME, SCM VAL)
     Corresponds to the Scheme ‘(define name val)’: it binds a value to
     the given name (which is a C string).  Returns the new object.

Pairs and lists
===============

 -- Function: SCM gh_cons (SCM A, SCM B)
 -- Function: SCM gh_list (SCM l0, SCM l1, ... , SCM_UNDEFINED)
     These correspond to the Scheme ‘(cons a b)’ and ‘(list l0 l1 ...)’
     procedures.  Note that ‘gh_list()’ is a C macro that invokes
     ‘scm_list_n()’.

 -- Function: SCM gh_car (SCM OBJ)
 -- Function: SCM gh_cdr (SCM OBJ)
     ...

 -- Function: SCM gh_c[ad][ad][ad][ad]r (SCM OBJ)
     These correspond to the Scheme ‘(caadar ls)’ procedures etc ...

 -- Function: SCM gh_set_car_x (SCM PAIR, SCM VALUE)
     Modifies the CAR of PAIR to be VALUE.  This is equivalent to the
     Scheme procedure ‘(set-car! ...)’.

 -- Function: SCM gh_set_cdr_x (SCM PAIR, SCM VALUE)
     Modifies the CDR of PAIR to be VALUE.  This is equivalent to the
     Scheme procedure ‘(set-cdr! ...)’.

 -- Function: unsigned long gh_length (SCM LS)
     Returns the length of the list.

 -- Function: SCM gh_append (SCM ARGS)
 -- Function: SCM gh_append2 (SCM L1, SCM L2)
 -- Function: SCM gh_append3 (SCM L1, SCM L2, L3)
 -- Function: SCM gh_append4 (SCM L1, SCM L2, L3, L4)
     ‘gh_append()’ takes ARGS, which is a list of lists ‘(list1 list2
     ...)’, and returns a list containing all the elements of the
     individual lists.

     A typical invocation of ‘gh_append()’ to append 5 lists together
     would be
            gh_append(gh_list(l1, l2, l3, l4, l5, SCM_UNDEFINED));

     The functions ‘gh_append2()’, ‘gh_append2()’, ‘gh_append3()’ and
     ‘gh_append4()’ are convenience routines to make it easier for C
     programs to form the list of lists that goes as an argument to
     ‘gh_append()’.

 -- Function: SCM gh_reverse (SCM LS)
     Returns a new list that has the same elements as LS but in the
     reverse order.  Note that this is implemented as a macro which
     calls ‘scm_reverse()’.

 -- Function: SCM gh_list_tail (SCM LS, SCM K)
     Returns the sublist of LS with the last K elements.

 -- Function: SCM gh_list_ref (SCM LS, SCM K)
     Returns the Kth element of the list LS.

 -- Function: SCM gh_memq (SCM X, SCM LS)
 -- Function: SCM gh_memv (SCM X, SCM LS)
 -- Function: SCM gh_member (SCM X, SCM LS)
     These functions return the first sublist of LS whose CAR is X.
     They correspond to ‘(memq x ls)’, ‘(memv x ls)’ and ‘(member x
     ls)’, and hence use (respectively) ‘eq?’, ‘eqv?’ and ‘equal?’ to do
     comparisons.

     If X does not appear in LS, the value ‘SCM_BOOL_F’ (not the empty
     list) is returned.

     Note that these functions are implemented as macros which call
     ‘scm_memq()’, ‘scm_memv()’ and ‘scm_member()’ respectively.

 -- Function: SCM gh_assq (SCM X, SCM ALIST)
 -- Function: SCM gh_assv (SCM X, SCM ALIST)
 -- Function: SCM gh_assoc (SCM X, SCM ALIST)
     These functions search an “association list” (list of pairs) ALIST
     for the first pair whose CAR is X, and they return that pair.

     If no pair in ALIST has X as its CAR, the value ‘SCM_BOOL_F’ (not
     the empty list) is returned.

     Note that these functions are implemented as macros which call
     ‘scm_assq()’, ‘scm_assv()’ and ‘scm_assoc()’ respectively.

Symbols
=======

Vectors
=======

 -- Function: SCM gh_make_vector (SCM N, SCM FILL)
 -- Function: SCM gh_vector (SCM LS)
 -- Function: SCM gh_vector_ref (SCM V, SCM I)
 -- Function: SCM gh_vector_set (SCM V, SCM I, SCM VAL)
 -- Function: unsigned long gh_vector_length (SCM V)
 -- Function: SCM gh_list_to_vector (SCM LS)
     These correspond to the Scheme ‘(make-vector n fill)’, ‘(vector a b
     c ...)’ ‘(vector-ref v i)’ ‘(vector-set v i value)’ ‘(vector-length
     v)’ ‘(list->vector ls)’ procedures.

     The correspondence is not perfect for ‘gh_vector’: this routine
     takes a list LS instead of the individual list elements, thus
     making it identical to ‘gh_list_to_vector’.

     There is also a difference in gh_vector_length: the value returned
     is a C ‘unsigned long’ instead of an SCM object.

Procedures
==========

 -- Function: SCM gh_apply (SCM proc, SCM args)
     Call the Scheme procedure PROC, with the elements of ARGS as
     arguments.  ARGS must be a proper list.

 -- Function: SCM gh_call0 (SCM proc)
 -- Function: SCM gh_call1 (SCM proc, SCM arg)
 -- Function: SCM gh_call2 (SCM proc, SCM arg1, SCM arg2)
 -- Function: SCM gh_call3 (SCM proc, SCM arg1, SCM arg2, SCM arg3)
     Call the Scheme procedure PROC with no arguments (‘gh_call0’), one
     argument (‘gh_call1’), and so on.  You can get the same effect by
     wrapping the arguments up into a list, and calling ‘gh_apply’;
     Guile provides these functions for convenience.

 -- Function: SCM gh_catch (SCM key, SCM thunk, SCM handler)
 -- Function: SCM gh_throw (SCM key, SCM args)
     Corresponds to the Scheme ‘catch’ and ‘throw’ procedures, which in
     Guile are provided as primitives.

 -- Function: SCM gh_is_eq (SCM a, SCM b)
 -- Function: SCM gh_is_eqv (SCM a, SCM b)
 -- Function: SCM gh_is_equal (SCM a, SCM b)
     These correspond to the Scheme ‘eq?’, ‘eqv?’ and ‘equal?’
     predicates.

 -- Function: int gh_obj_length (SCM OBJ)
     Returns the raw object length.

Data lookup
===========

For now I just include Tim Pierce's comments from the ‘gh_data.c’ file;
it should be organized into a documentation of the two functions here.

     /* Data lookups between C and Scheme

        Look up a symbol with a given name, and return the object to which
        it is bound.  gh_lookup examines the Guile top level, and
        gh_module_lookup checks the module name space specified by the
        `vec' argument.

        The return value is the Scheme object to which SNAME is bound, or
        SCM_UNDEFINED if SNAME is not bound in the given context. [FIXME:
        should this be SCM_UNSPECIFIED?  Can a symbol ever legitimately be
        bound to SCM_UNDEFINED or SCM_UNSPECIFIED?  What is the difference?
        -twp] */


File: guile.info,  Node: Guile Modules,  Next: Autoconf Support,  Prev: API Reference,  Up: Top

6 Guile Modules
***************

* Menu:

* SLIB::                        Using the SLIB Scheme library.
* POSIX::                       POSIX system calls and networking.
* getopt-long::                 Command line handling.
* SRFI Support::                Support for various SRFIs.
* Readline Support::            Module for using the readline library.
* Value History::               Maintaining a value history in the REPL.
* Pretty Printing::             Nicely formatting Scheme objects for output.
* Formatted Output::            The ‘format’ procedure.
* File Tree Walk::              Traversing the file system.
* Queues::                      First-in first-out queuing.
* Streams::                     Sequences of values.
* Buffered Input::              Ports made from a reader function.
* Expect::			Controlling interactive programs with Guile.
* The Scheme shell (scsh)::     Using scsh interfaces in Guile.
* Tracing::                     Tracing program execution.


File: guile.info,  Node: SLIB,  Next: POSIX,  Up: Guile Modules

6.1 SLIB
========

Before the SLIB facilities can be used, the following Scheme expression
must be executed:

     (use-modules (ice-9 slib))

   ‘require’ can then be used in the usual way (*note (slib)Require::).
For example,

     (use-modules (ice-9 slib))
     (require 'primes)
     (prime? 13)
     ⇒ #t

   A few Guile core functions are overridden by the SLIB setups; for
example the SLIB version of ‘delete-file’ returns a boolean indicating
success or failure, whereas the Guile core version throws an error for
failure.  In general (and as might be expected) when SLIB is loaded it's
the SLIB specifications that are followed.

* Menu:

* SLIB installation::
* JACAL::


File: guile.info,  Node: SLIB installation,  Next: JACAL,  Up: SLIB

6.1.1 SLIB installation
-----------------------

The following procedure works, e.g., with SLIB version 3a3 (*note SLIB
installation: (slib)Installation.):

  1. Unpack SLIB and install it using ‘make install’ from its directory.
     By default, this will install SLIB in ‘/usr/local/lib/slib/’.
     Running ‘make installinfo’ installs its documentation, by default
     under ‘/usr/local/info/’.

  2. Define the ‘SCHEME_LIBRARY_PATH’ environment variable:

          $ SCHEME_LIBRARY_PATH=/usr/local/lib/slib/
          $ export SCHEME_LIBRARY_PATH

     Alternatively, you can create a symlink in the Guile directory to
     SLIB, e.g.:

          ln -s /usr/local/lib/slib /usr/local/share/guile/1.8/slib

  3. Use Guile to create the catalog file, e.g.,:

          # guile
          guile> (use-modules (ice-9 slib))
          guile> (require 'new-catalog)
          guile> (quit)

     The catalog data should now be in
     ‘/usr/local/share/guile/1.8/slibcat’.

     If instead you get an error such as:

          Unbound variable: scheme-implementation-type

     then a solution is to get a newer version of Guile, or to modify
     ‘ice-9/slib.scm’ to use ‘define-public’ for the offending
     variables.


File: guile.info,  Node: JACAL,  Prev: SLIB installation,  Up: SLIB

6.1.2 JACAL
-----------

Jacal is a symbolic math package written in Scheme by Aubrey Jaffer.  It
is usually installed as an extra package in SLIB.

   You can use Guile's interface to SLIB to invoke Jacal:

     (use-modules (ice-9 slib))
     (slib:load "math")
     (math)

For complete documentation on Jacal, please read the Jacal manual.  If
it has been installed on line, you can look at *note Jacal: (jacal)Top.
Otherwise you can find it on the web at
<http://www-swiss.ai.mit.edu/~jaffer/JACAL.html>


File: guile.info,  Node: POSIX,  Next: getopt-long,  Prev: SLIB,  Up: Guile Modules

6.2 POSIX System Calls and Networking
=====================================

* Menu:

* Conventions::                 Conventions employed by the POSIX interface.
* Ports and File Descriptors::  Scheme "ports" and Unix file descriptors
                                  have different representations.
* File System::                 stat, chown, chmod, etc.
* User Information::            Retrieving a user's GECOS (/etc/passwd) entry.
* Time::                        gettimeofday, localtime, strftime, etc.
* Runtime Environment::         Accessing and modifying Guile's environment.
* Processes::                   getuid, getpid, etc.
* Signals::                     sigaction, kill, pause, alarm, setitimer, etc.
* Terminals and Ptys::          ttyname, tcsetpgrp, etc.
* Pipes::                       Communicating data between processes.
* Networking::                  gethostbyaddr, getnetent, socket, bind, listen.
* System Identification::       Obtaining information about the system.
* Locales::                     setlocale, etc.
* Encryption::


File: guile.info,  Node: Conventions,  Next: Ports and File Descriptors,  Up: POSIX

6.2.1 POSIX Interface Conventions
---------------------------------

These interfaces provide access to operating system facilities.  They
provide a simple wrapping around the underlying C interfaces to make
usage from Scheme more convenient.  They are also used to implement the
Guile port of scsh (*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.  In some cases procedures which can't be
implemented on particular systems may become no-ops, or perform limited
actions.  In other cases they may throw errors.

   General naming conventions are as follows:

   • The Scheme name is often identical to the name of the underlying
     Unix facility.
   • Underscores in Unix procedure names are converted to hyphens.
   • Procedures which destructively modify Scheme data have exclamation
     marks appended, e.g., ‘recv!’.
   • Predicates (returning only ‘#t’ or ‘#f’) have question marks
     appended, 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).

   Unexpected conditions are generally 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 are noted in the documentation.

   For ways to deal with exceptions, see *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 with ‘scm-error’ (*note Error Reporting::).  The DATA
parameter is a list containing the Unix ‘errno’ value (an integer).  For
example,

     (define (my-handler key func fmt fmtargs data)
       (display key) (newline)
       (display func) (newline)
       (apply format #t fmt fmtargs) (newline)
       (display data) (newline))

     (catch 'system-error
       (lambda () (dup2 -123 -456))
       my-handler)

     ⊣
     system-error
     dup2
     Bad file descriptor
     (9)


 -- Function: system-error-errno arglist
     Return the ‘errno’ value from a list which is the arguments to an
     exception handler.  If the exception is not a ‘system-error’, then
     the return is ‘#f’.  For example,

          (catch
           'system-error
           (lambda ()
             (mkdir "/this-ought-to-fail-if-I'm-not-root"))
           (lambda stuff
             (let ((errno (system-error-errno stuff)))
               (cond
                ((= errno EACCES)
                 (display "You're not allowed to do that."))
                ((= errno EEXIST)
                 (display "Already exists."))
                (#t
                 (display (strerror errno))))
               (newline))))


File: guile.info,  Node: Ports and File Descriptors,  Next: File System,  Prev: Conventions,  Up: POSIX

6.2.2 Ports and File Descriptors
--------------------------------

Conventions generally follow those of scsh, *note The Scheme shell
(scsh)::.

   File ports are implemented using low-level operating system I/O
facilities, with optional buffering to improve efficiency; see *note
File Ports::.

   Note that some procedures (e.g., ‘recv!’) will accept ports as
arguments, but will actually operate directly on the file descriptor
underlying the port.  Any port buffering is ignored, including the
buffer which implements ‘peek-char’ and ‘unread-char’.

   The ‘force-output’ and ‘drain-input’ procedures can be used to clear
the buffers.

   Each open file port has an associated operating system file
descriptor.  File descriptors are generally not useful in Scheme
programs; however they may be needed when interfacing with foreign code
and the Unix environment.

   A file descriptor can be extracted from a port and a new port can be
created from a file descriptor.  However a file descriptor is just an
integer and the garbage collector doesn't recognize it as a reference to
the port.  If all other references to the port were dropped, then it's
likely that the garbage collector would free the port, with the
side-effect of closing the file descriptor prematurely.

   To assist the programmer in avoiding this problem, each port has an
associated “revealed count” which can be used to keep track of how many
times the underlying file descriptor has been stored in other places.
If a port's revealed count is greater than zero, the file descriptor
will not be closed when the port is garbage collected.  A programmer can
therefore ensure that the revealed count will be greater than zero if
the file descriptor is needed elsewhere.

   For the simple case where a file descriptor is "imported" once to
become a port, it does not matter if the file descriptor is closed when
the port is garbage collected.  There is no need to maintain a revealed
count.  Likewise when "exporting" a file descriptor to the external
environment, setting the revealed count is not required provided the
port is kept open (i.e., is pointed to by a live Scheme binding) while
the file descriptor is in use.

   To correspond with traditional Unix behaviour, three file descriptors
(0, 1, and 2) are automatically imported when a program starts up and
assigned to the initial values of the current/standard input, output,
and error ports, respectively.  The revealed count for each is initially
set to one, so that dropping references to one of these ports will not
result in its garbage collection: it could be retrieved with ‘fdopen’ or
‘fdes->ports’.

 -- Scheme Procedure: port-revealed port
 -- C Function: scm_port_revealed (port)
     Return the revealed count for PORT.

 -- Scheme Procedure: set-port-revealed! port rcount
 -- C Function: scm_set_port_revealed_x (port, rcount)
     Sets the revealed count for a PORT to RCOUNT.  The return value is
     unspecified.

 -- Scheme Procedure: fileno port
 -- C Function: scm_fileno (port)
     Return the integer file descriptor underlying PORT.  Does not
     change its revealed count.

 -- Scheme Procedure: port->fdes port
     Returns the integer file descriptor underlying PORT.  As a side
     effect the revealed count of PORT is incremented.

 -- Scheme Procedure: fdopen fdes modes
 -- C Function: scm_fdopen (fdes, modes)
     Return a new port based on the file descriptor FDES.  Modes are
     given by the string MODES.  The revealed count of the port is
     initialized to zero.  The MODES string is the same as that accepted
     by ‘open-file’ (*note open-file: File Ports.).

 -- Scheme Procedure: fdes->ports fd
 -- C Function: scm_fdes_to_ports (fd)
     Return a list of existing ports which have FDES as an underlying
     file descriptor, without changing their revealed counts.

 -- Scheme Procedure: fdes->inport fdes
     Returns an existing input port which has FDES as its underlying
     file descriptor, if one exists, and increments its revealed count.
     Otherwise, returns a new input port with a revealed count of 1.

 -- Scheme Procedure: fdes->outport fdes
     Returns an existing output port which has FDES as its underlying
     file descriptor, if one exists, and increments its revealed count.
     Otherwise, returns a new output port with a revealed count of 1.

 -- Scheme Procedure: primitive-move->fdes port fd
 -- C Function: scm_primitive_move_to_fdes (port, fd)
     Moves the underlying file descriptor for PORT to the integer value
     FDES without changing the revealed count of PORT.  Any other ports
     already using this descriptor will be automatically shifted to new
     descriptors and their revealed counts reset to zero.  The return
     value is ‘#f’ if the file descriptor already had the required value
     or ‘#t’ if it was moved.

 -- Scheme Procedure: move->fdes port fdes
     Moves the underlying file descriptor for PORT to the integer value
     FDES and sets its revealed count to one.  Any other ports already
     using this descriptor will be automatically shifted to new
     descriptors and their revealed counts reset to zero.  The return
     value is unspecified.

 -- Scheme Procedure: release-port-handle port
     Decrements the revealed count for a port.

 -- Scheme Procedure: fsync object
 -- C Function: scm_fsync (object)
     Copies any unwritten data for the specified output file descriptor
     to disk.  If PORT/FD is a port, its buffer is flushed before the
     underlying file descriptor is fsync'd.  The return value is
     unspecified.

 -- Scheme Procedure: open path flags [mode]
 -- C Function: scm_open (path, flags, mode)
     Open the file named by PATH for reading and/or writing.  FLAGS is
     an integer specifying how the file should be opened.  MODE is an
     integer specifying the permission bits of the file, if it needs to
     be created, before the umask (*note Processes::) is applied.  The
     default is 666 (Unix itself has no default).

     FLAGS can be constructed by combining variables using ‘logior’.
     Basic flags are:

      -- Variable: O_RDONLY
          Open the file read-only.
      -- Variable: O_WRONLY
          Open the file write-only.
      -- Variable: O_RDWR
          Open the file read/write.
      -- Variable: O_APPEND
          Append to the file instead of truncating.
      -- Variable: O_CREAT
          Create the file if it does not already exist.

     *Note (libc)File Status Flags::, for additional flags.

 -- Scheme Procedure: open-fdes path flags [mode]
 -- C Function: scm_open_fdes (path, flags, mode)
     Similar to ‘open’ but return a file descriptor instead of a port.

 -- Scheme Procedure: close fd_or_port
 -- C Function: scm_close (fd_or_port)
     Similar to ‘close-port’ (*note close-port: Closing.), but also
     works on file descriptors.  A side effect of closing a file
     descriptor is that any ports using that file descriptor are moved
     to a different file descriptor and have their revealed counts set
     to zero.

 -- Scheme Procedure: close-fdes fd
 -- C Function: scm_close_fdes (fd)
     A simple wrapper for the ‘close’ system call.  Close file
     descriptor FD, which must be an integer.  Unlike ‘close’, the file
     descriptor will be closed even if a port is using it.  The return
     value is unspecified.

 -- Scheme Procedure: unread-char char [port]
 -- C Function: scm_unread_char (char, port)
     Place CHAR in PORT so that it will be read by the next read
     operation on that port.  If called multiple times, the unread
     characters will be read again in "last-in, first-out" order (i.e. a
     stack).  If PORT is not supplied, the current input port is used.

 -- Scheme Procedure: unread-string str port
     Place the string STR in PORT so that its characters will be read in
     subsequent read operations.  If called multiple times, the unread
     characters will be read again in last-in first-out order.  If PORT
     is not supplied, the current-input-port is used.

 -- Scheme Procedure: pipe
 -- C Function: scm_pipe ()
     Return a newly created pipe: a pair of ports which are linked
     together on the local machine.  The CAR is the input port and the
     CDR is the output port.  Data written (and flushed) to the output
     port can be read from the input port.  Pipes are commonly used for
     communication with a newly forked child process.  The need to flush
     the output port can be avoided by making it unbuffered using
     ‘setvbuf’.

      -- Variable: PIPE_BUF
          A write of up to ‘PIPE_BUF’ many bytes to a pipe is atomic,
          meaning when done it goes into the pipe instantaneously and as
          a contiguous block (*note Atomicity of Pipe I/O: (libc)Pipe
          Atomicity.).

     Note that the output port is likely to block if too much data has
     been written but not yet read from the input port.  Typically the
     capacity is ‘PIPE_BUF’ bytes.

   The next group of procedures perform a ‘dup2’ system call, if NEWFD
(an integer) is supplied, otherwise a ‘dup’.  The file descriptor to be
duplicated can be supplied as an integer or contained in a port.  The
type of value returned varies depending on which procedure is used.

   All procedures also have the side effect when performing ‘dup2’ that
any ports using NEWFD are moved to a different file descriptor and have
their revealed counts set to zero.

 -- Scheme Procedure: dup->fdes fd_or_port [fd]
 -- C Function: scm_dup_to_fdes (fd_or_port, fd)
     Return a new integer file descriptor referring to the open file
     designated by FD_OR_PORT, which must be either an open file port or
     a file descriptor.

 -- Scheme Procedure: dup->inport port/fd [newfd]
     Returns a new input port using the new file descriptor.

 -- Scheme Procedure: dup->outport port/fd [newfd]
     Returns a new output port using the new file descriptor.

 -- Scheme Procedure: dup port/fd [newfd]
     Returns a new port if PORT/FD is a port, with the same mode as the
     supplied port, otherwise returns an integer file descriptor.

 -- Scheme Procedure: dup->port port/fd mode [newfd]
     Returns a new port using the new file descriptor.  MODE supplies a
     mode string for the port (*note open-file: File Ports.).

 -- Scheme Procedure: duplicate-port port modes
     Returns a new port which is opened on a duplicate of the file
     descriptor underlying PORT, with mode string MODES as for *note
     open-file: File Ports.  The two ports will share a file position
     and file status flags.

     Unexpected behaviour can result if both ports are subsequently used
     and the original and/or duplicate ports are buffered.  The mode
     string can include ‘0’ to obtain an unbuffered duplicate port.

     This procedure is equivalent to ‘(dup->port PORT MODES)’.

 -- Scheme Procedure: redirect-port old new
 -- C Function: scm_redirect_port (old, new)
     This procedure takes two ports and duplicates the underlying file
     descriptor from OLD-PORT into NEW-PORT.  The current file
     descriptor in NEW-PORT will be closed.  After the redirection the
     two ports will share a file position and file status flags.

     The return value is unspecified.

     Unexpected behaviour can result if both ports are subsequently used
     and the original and/or duplicate ports are buffered.

     This procedure does not have any side effects on other ports or
     revealed counts.

 -- Scheme Procedure: dup2 oldfd newfd
 -- C Function: scm_dup2 (oldfd, newfd)
     A simple wrapper for the ‘dup2’ system call.  Copies the file
     descriptor OLDFD to descriptor number NEWFD, replacing the previous
     meaning of NEWFD.  Both OLDFD and NEWFD must be integers.  Unlike
     for ‘dup->fdes’ or ‘primitive-move->fdes’, no attempt is made to
     move away ports which are using NEWFD.  The return value is
     unspecified.

 -- Scheme Procedure: port-mode port
     Return the port modes associated with the open port PORT.  These
     will not necessarily be identical to the modes used when the port
     was opened, since modes such as "append" which are used only during
     port creation are not retained.

 -- Scheme Procedure: port-for-each proc
 -- C Function: scm_port_for_each (SCM proc)
 -- C Function: scm_c_port_for_each (void (*proc)(void *, SCM), void
          *data)
     Apply PROC to each port in the Guile port table (FIXME: what is the
     Guile port table?)  in turn.  The return value is unspecified.
     More specifically, PROC is applied exactly once to every port that
     exists in the system at the time ‘port-for-each’ is invoked.
     Changes to the port table while ‘port-for-each’ is running have no
     effect as far as ‘port-for-each’ is concerned.

     The C function ‘scm_port_for_each’ takes a Scheme procedure encoded
     as a ‘SCM’ value, while ‘scm_c_port_for_each’ takes a pointer to a
     C function and passes along a arbitrary DATA cookie.

 -- Scheme Procedure: setvbuf port mode [size]
 -- C Function: scm_setvbuf (port, mode, size)
     Set the buffering mode for PORT.  MODE can be:

      -- Variable: _IONBF
          non-buffered
      -- Variable: _IOLBF
          line buffered
      -- Variable: _IOFBF
          block buffered, using a newly allocated buffer of SIZE bytes.
          If SIZE is omitted, a default size will be used.

 -- Scheme Procedure: fcntl port/fd cmd [value]
 -- C Function: scm_fcntl (object, cmd, value)
     Apply CMD on PORT/FD, either a port or file descriptor.  The VALUE
     argument is used by the ‘SET’ commands described below, it's an
     integer value.

     Values for CMD are:

      -- Variable: F_DUPFD
          Duplicate the file descriptor, the same as ‘dup->fdes’ above
          does.

      -- Variable: F_GETFD
      -- Variable: F_SETFD
          Get or set flags associated with the file descriptor.  The
          only flag is the following,

           -- Variable: FD_CLOEXEC
               "Close on exec", meaning the file descriptor will be
               closed on an ‘exec’ call (a successful such call).  For
               example to set that flag,

                    (fcntl port F_SETFD FD_CLOEXEC)

               Or better, set it but leave any other possible future
               flags unchanged,

                    (fcntl port F_SETFD (logior FD_CLOEXEC
                                                (fcntl port F_GETFD)))

      -- Variable: F_GETFL
      -- Variable: F_SETFL
          Get or set flags associated with the open file.  These flags
          are ‘O_RDONLY’ etc described under ‘open’ above.

          A common use is to set ‘O_NONBLOCK’ on a network socket.  The
          following sets that flag, and leaves other flags unchanged.

               (fcntl sock F_SETFL (logior O_NONBLOCK
                                           (fcntl sock F_GETFL)))

      -- Variable: F_GETOWN
      -- Variable: F_SETOWN
          Get or set the process ID of a socket's owner, for ‘SIGIO’
          signals.

 -- Scheme Procedure: flock file operation
 -- C Function: scm_flock (file, operation)
     Apply or remove an advisory lock on an open file.  OPERATION
     specifies the action to be done:

      -- Variable: LOCK_SH
          Shared lock.  More than one process may hold a shared lock for
          a given file at a given time.
      -- Variable: LOCK_EX
          Exclusive lock.  Only one process may hold an exclusive lock
          for a given file at a given time.
      -- Variable: LOCK_UN
          Unlock the file.
      -- Variable: LOCK_NB
          Don't block when locking.  This is combined with one of the
          other operations using ‘logior’ (*note Bitwise Operations::).
          If ‘flock’ would block an ‘EWOULDBLOCK’ error is thrown (*note
          Conventions::).

     The return value is not specified.  FILE may be an open file
     descriptor or an open file descriptor port.

     Note that ‘flock’ does not lock files across NFS.

 -- Scheme Procedure: select reads writes excepts [secs [usecs]]
 -- C Function: scm_select (reads, writes, excepts, secs, usecs)
     This procedure has a variety of uses: waiting for the ability to
     provide input, accept output, or the existence of exceptional
     conditions on a collection of ports or file descriptors, or waiting
     for a timeout to occur.  It also returns if interrupted by a
     signal.

     READS, WRITES and EXCEPTS can be lists or vectors, with each member
     a port or a file descriptor.  The value returned is a list of three
     corresponding lists or vectors containing only the members which
     meet the specified requirement.  The ability of port buffers to
     provide input or accept output is taken into account.  Ordering of
     the input lists or vectors is not preserved.

     The optional arguments SECS and USECS specify the timeout.  Either
     SECS can be specified alone, as either an integer or a real number,
     or both SECS and USECS can be specified as integers, in which case
     USECS is an additional timeout expressed in microseconds.  If SECS
     is omitted or is ‘#f’ then select will wait for as long as it takes
     for one of the other conditions to be satisfied.

     The scsh version of ‘select’ differs as follows: Only vectors are
     accepted for the first three arguments.  The USECS argument is not
     supported.  Multiple values are returned instead of a list.
     Duplicates in the input vectors appear only once in output.  An
     additional ‘select!’ interface is provided.


File: guile.info,  Node: File System,  Next: User Information,  Prev: Ports and File Descriptors,  Up: POSIX

6.2.3 File System
-----------------

These procedures allow querying and setting file system attributes (such
as owner, permissions, sizes and types of files); deleting, copying,
renaming and linking files; creating and removing directories and
querying their contents; syncing the file system and creating special
files.

 -- Scheme Procedure: access? path how
 -- C Function: scm_access (path, how)
     Test accessibility of a file under the real UID and GID of the
     calling process.  The return is ‘#t’ if PATH exists and the
     permissions requested by HOW are all allowed, or ‘#f’ if not.

     HOW is an integer which is one of the following values, or a
     bitwise-OR (‘logior’) of multiple values.

      -- Variable: R_OK
          Test for read permission.
      -- Variable: W_OK
          Test for write permission.
      -- Variable: X_OK
          Test for execute permission.
      -- Variable: F_OK
          Test for existence of the file.  This is implied by each of
          the other tests, so there's no need to combine it with them.

     It's important to note that ‘access?’ does not simply indicate what
     will happen on attempting to read or write a file.  In normal
     circumstances it does, but in a set-UID or set-GID program it
     doesn't because ‘access?’ tests the real ID, whereas an open or
     execute attempt uses the effective ID.

     A program which will never run set-UID/GID can ignore the
     difference between real and effective IDs, but for maximum
     generality, especially in library functions, it's best not to use
     ‘access?’ to predict the result of an open or execute, instead
     simply attempt that and catch any exception.

     The main use for ‘access?’ is to let a set-UID/GID program
     determine what the invoking user would have been allowed to do,
     without the greater (or perhaps lesser) privileges afforded by the
     effective ID. For more on this, see *note (libc)Testing File
     Access::.

 -- Scheme Procedure: stat object
 -- C Function: scm_stat (object)
     Return an object containing various information about the file
     determined by OBJ.  OBJ can be a string containing a file name or a
     port or integer file descriptor which is open on a file (in which
     case ‘fstat’ is used as the underlying system call).

     The object returned by ‘stat’ can be passed as a single parameter
     to the following procedures, all of which return integers:

      -- Scheme Procedure: stat:dev st
          The device number containing the file.
      -- Scheme Procedure: stat:ino st
          The file serial number, which distinguishes this file from all
          other files on the same device.
      -- Scheme Procedure: stat:mode st
          The mode of the file.  This is an integer which incorporates
          file type information and file permission bits.  See also
          ‘stat:type’ and ‘stat:perms’ below.
      -- Scheme Procedure: stat:nlink st
          The number of hard links to the file.
      -- Scheme Procedure: stat:uid st
          The user ID of the file's owner.
      -- Scheme Procedure: stat:gid st
          The group ID of the file.
      -- Scheme Procedure: stat:rdev st
          Device ID; this entry is defined only for character or block
          special files.  On some systems this field is not available at
          all, in which case ‘stat:rdev’ returns ‘#f’.
      -- Scheme Procedure: stat:size st
          The size of a regular file in bytes.
      -- Scheme Procedure: stat:atime st
          The last access time for the file.
      -- Scheme Procedure: stat:mtime st
          The last modification time for the file.
      -- Scheme Procedure: stat:ctime st
          The last modification time for the attributes of the file.
      -- Scheme Procedure: stat:blksize st
          The optimal block size for reading or writing the file, in
          bytes.  On some systems this field is not available, in which
          case ‘stat:blksize’ returns a sensible suggested block size.
      -- Scheme Procedure: stat:blocks st
          The amount of disk space that the file occupies measured in
          units of 512 byte blocks.  On some systems this field is not
          available, in which case ‘stat:blocks’ returns ‘#f’.

     In addition, the following procedures return the information from
     ‘stat:mode’ in a more convenient form:

      -- Scheme Procedure: stat:type st
          A symbol representing the type of file.  Possible values are
          ‘regular’, ‘directory’, ‘symlink’, ‘block-special’,
          ‘char-special’, ‘fifo’, ‘socket’, and ‘unknown’.
      -- Scheme Procedure: stat:perms st
          An integer representing the access permission bits.

 -- Scheme Procedure: lstat str
 -- C Function: scm_lstat (str)
     Similar to ‘stat’, but does not follow symbolic links, i.e., it
     will return information about a symbolic link itself, not the file
     it points to.  PATH must be a string.

 -- Scheme Procedure: readlink path
 -- C Function: scm_readlink (path)
     Return the value of the symbolic link named by PATH (a string),
     i.e., the file that the link points to.

 -- Scheme Procedure: chown object owner group
 -- C Function: scm_chown (object, owner, group)
     Change the ownership and group of the file referred to by OBJECT to
     the integer values OWNER and GROUP.  OBJECT can be a string
     containing a file name or, if the platform supports ‘fchown’ (*note
     (libc)File Owner::), a port or integer file descriptor which is
     open on the file.  The return value is unspecified.

     If OBJECT is a symbolic link, either the ownership of the link or
     the ownership of the referenced file will be changed depending on
     the operating system (lchown is unsupported at present).  If OWNER
     or GROUP is specified as ‘-1’, then that ID is not changed.

 -- Scheme Procedure: chmod object mode
 -- C Function: scm_chmod (object, mode)
     Changes the permissions of the file referred to by OBJ.  OBJ can be
     a string containing a file name or a port or integer file
     descriptor which is open on a file (in which case ‘fchmod’ is used
     as the underlying system call).  MODE specifies the new permissions
     as a decimal number, e.g., ‘(chmod "foo" #o755)’.  The return value
     is unspecified.

 -- Scheme Procedure: utime pathname [actime [modtime]]
 -- C Function: scm_utime (pathname, actime, modtime)
     ‘utime’ sets the access and modification times for the file named
     by PATH.  If ACTIME or MODTIME is not supplied, then the current
     time is used.  ACTIME and MODTIME must be integer time values as
     returned by the ‘current-time’ procedure.
          (utime "foo" (- (current-time) 3600))
     will set the access time to one hour in the past and the
     modification time to the current time.

 -- Scheme Procedure: delete-file str
 -- C Function: scm_delete_file (str)
     Deletes (or "unlinks") the file whose path is specified by STR.

 -- Scheme Procedure: copy-file oldfile newfile
 -- C Function: scm_copy_file (oldfile, newfile)
     Copy the file specified by OLDFILE to NEWFILE.  The return value is
     unspecified.

 -- Scheme Procedure: rename-file oldname newname
 -- C Function: scm_rename (oldname, newname)
     Renames the file specified by OLDNAME to NEWNAME.  The return value
     is unspecified.

 -- Scheme Procedure: link oldpath newpath
 -- C Function: scm_link (oldpath, newpath)
     Creates a new name NEWPATH in the file system for the file named by
     OLDPATH.  If OLDPATH is a symbolic link, the link may or may not be
     followed depending on the system.

 -- Scheme Procedure: symlink oldpath newpath
 -- C Function: scm_symlink (oldpath, newpath)
     Create a symbolic link named NEWPATH with the value (i.e., pointing
     to) OLDPATH.  The return value is unspecified.

 -- Scheme Procedure: mkdir path [mode]
 -- C Function: scm_mkdir (path, mode)
     Create a new directory named by PATH.  If MODE is omitted then the
     permissions of the directory file are set using the current umask
     (*note Processes::).  Otherwise they are set to the decimal value
     specified with MODE.  The return value is unspecified.

 -- Scheme Procedure: rmdir path
 -- C Function: scm_rmdir (path)
     Remove the existing directory named by PATH.  The directory must be
     empty for this to succeed.  The return value is unspecified.

 -- Scheme Procedure: opendir dirname
 -- C Function: scm_opendir (dirname)
     Open the directory specified by DIRNAME and return a directory
     stream.

 -- Scheme Procedure: directory-stream? object
 -- C Function: scm_directory_stream_p (object)
     Return a boolean indicating whether OBJECT is a directory stream as
     returned by ‘opendir’.

 -- Scheme Procedure: readdir stream
 -- C Function: scm_readdir (stream)
     Return (as a string) the next directory entry from the directory
     stream STREAM.  If there is no remaining entry to be read then the
     end of file object is returned.

 -- Scheme Procedure: rewinddir stream
 -- C Function: scm_rewinddir (stream)
     Reset the directory port STREAM so that the next call to ‘readdir’
     will return the first directory entry.

 -- Scheme Procedure: closedir stream
 -- C Function: scm_closedir (stream)
     Close the directory stream STREAM.  The return value is
     unspecified.

   Here is an example showing how to display all the entries in a
directory:

     (define dir (opendir "/usr/lib"))
     (do ((entry (readdir dir) (readdir dir)))
         ((eof-object? entry))
       (display entry)(newline))
     (closedir dir)

 -- Scheme Procedure: sync
 -- C Function: scm_sync ()
     Flush the operating system disk buffers.  The return value is
     unspecified.

 -- Scheme Procedure: mknod path type perms dev
 -- C Function: scm_mknod (path, type, perms, dev)
     Creates a new special file, such as a file corresponding to a
     device.  PATH specifies the name of the file.  TYPE should be one
     of the following symbols: ‘regular’, ‘directory’, ‘symlink’,
     ‘block-special’, ‘char-special’, ‘fifo’, or ‘socket’.  PERMS (an
     integer) specifies the file permissions.  DEV (an integer)
     specifies which device the special file refers to.  Its exact
     interpretation depends on the kind of special file being created.

     E.g.,
          (mknod "/dev/fd0" 'block-special #o660 (+ (* 2 256) 2))

     The return value is unspecified.

 -- Scheme Procedure: tmpnam
 -- C Function: scm_tmpnam ()
     Return an auto-generated name of a temporary file, a file which
     doesn't already exist.  The name includes a path, it's usually in
     ‘/tmp’ but that's system dependent.

     Care must be taken when using ‘tmpnam’.  In between choosing the
     name and creating the file another program might use that name, or
     an attacker might even make it a symlink pointing at something
     important and causing you to overwrite that.

     The safe way is to create the file using ‘open’ with ‘O_EXCL’ to
     avoid any overwriting.  A loop can try again with another name if
     the file exists (error ‘EEXIST’).  ‘mkstemp!’ below does that.

 -- Scheme Procedure: mkstemp! tmpl
 -- C Function: scm_mkstemp (tmpl)
     Create a new unique file in the file system and return a new
     buffered port open for reading and writing to the file.

     TMPL is a string specifying where the file should be created: it
     must end with ‘XXXXXX’ and those ‘X’s will be changed in the string
     to return the name of the file.  (‘port-filename’ on the port also
     gives the name.)

     POSIX doesn't specify the permissions mode of the file, on GNU and
     most systems it's ‘#o600’.  An application can use ‘chmod’ to relax
     that if desired.  For example ‘#o666’ less ‘umask’, which is usual
     for ordinary file creation,

          (let ((port (mkstemp! (string-copy "/tmp/myfile-XXXXXX"))))
            (chmod port (logand #o666 (lognot (umask))))
            ...)

 -- Scheme Procedure: dirname filename
 -- C Function: scm_dirname (filename)
     Return the directory name component of the file name FILENAME.  If
     FILENAME does not contain a directory component, ‘.’ is returned.

 -- Scheme Procedure: basename filename [suffix]
 -- C Function: scm_basename (filename, suffix)
     Return the base name of the file name FILENAME.  The base name is
     the file name without any directory components.  If SUFFIX is
     provided, and is equal to the end of BASENAME, it is removed also.

          (basename "/tmp/test.xml" ".xml")
          ⇒ "test"

 -- Scheme Procedure: file-exists? filename
     Return ‘#t’ if the file named FILENAME exists, ‘#f’ if not.


File: guile.info,  Node: User Information,  Next: Time,  Prev: File System,  Up: POSIX

6.2.4 User Information
----------------------

The facilities in this section provide an interface to the user and
group database.  They should be used with care since they are not
reentrant.

   The following functions accept an object representing user
information and return a selected component:

 -- Scheme Procedure: passwd:name pw
     The name of the userid.
 -- Scheme Procedure: passwd:passwd pw
     The encrypted passwd.
 -- Scheme Procedure: passwd:uid pw
     The user id number.
 -- Scheme Procedure: passwd:gid pw
     The group id number.
 -- Scheme Procedure: passwd:gecos pw
     The full name.
 -- Scheme Procedure: passwd:dir pw
     The home directory.
 -- Scheme Procedure: passwd:shell pw
     The login shell.

 -- Scheme Procedure: getpwuid uid
     Look up an integer userid in the user database.

 -- Scheme Procedure: getpwnam name
     Look up a user name string in the user database.

 -- Scheme Procedure: setpwent
     Initializes a stream used by ‘getpwent’ to read from the user
     database.  The next use of ‘getpwent’ will return the first entry.
     The return value is unspecified.

 -- Scheme Procedure: getpwent
     Read the next entry in the user database stream.  The return is a
     passwd user object as above, or ‘#f’ when no more entries.

 -- Scheme Procedure: endpwent
     Closes the stream used by ‘getpwent’.  The return value is
     unspecified.

 -- Scheme Procedure: setpw [arg]
 -- C Function: scm_setpwent (arg)
     If called with a true argument, initialize or reset the password
     data stream.  Otherwise, close the stream.  The ‘setpwent’ and
     ‘endpwent’ procedures are implemented on top of this.

 -- Scheme Procedure: getpw [user]
 -- C Function: scm_getpwuid (user)
     Look up an entry in the user database.  OBJ can be an integer, a
     string, or omitted, giving the behaviour of getpwuid, getpwnam or
     getpwent respectively.

   The following functions accept an object representing group
information and return a selected component:

 -- Scheme Procedure: group:name gr
     The group name.
 -- Scheme Procedure: group:passwd gr
     The encrypted group password.
 -- Scheme Procedure: group:gid gr
     The group id number.
 -- Scheme Procedure: group:mem gr
     A list of userids which have this group as a supplementary group.

 -- Scheme Procedure: getgrgid gid
     Look up an integer group id in the group database.

 -- Scheme Procedure: getgrnam name
     Look up a group name in the group database.

 -- Scheme Procedure: setgrent
     Initializes a stream used by ‘getgrent’ to read from the group
     database.  The next use of ‘getgrent’ will return the first entry.
     The return value is unspecified.

 -- Scheme Procedure: getgrent
     Return the next entry in the group database, using the stream set
     by ‘setgrent’.

 -- Scheme Procedure: endgrent
     Closes the stream used by ‘getgrent’.  The return value is
     unspecified.

 -- Scheme Procedure: setgr [arg]
 -- C Function: scm_setgrent (arg)
     If called with a true argument, initialize or reset the group data
     stream.  Otherwise, close the stream.  The ‘setgrent’ and
     ‘endgrent’ procedures are implemented on top of this.

 -- Scheme Procedure: getgr [name]
 -- C Function: scm_getgrgid (name)
     Look up an entry in the group database.  OBJ can be an integer, a
     string, or omitted, giving the behaviour of getgrgid, getgrnam or
     getgrent respectively.

   In addition to the accessor procedures for the user database, the
following shortcut procedures are also available.

 -- Scheme Procedure: cuserid
 -- C Function: scm_cuserid ()
     Return a string containing a user name associated with the
     effective user id of the process.  Return ‘#f’ if this information
     cannot be obtained.

     This function has been removed from the latest POSIX specification,
     Guile provides it only if the system has it.  Using ‘(getpwuid
     (geteuid))’ may be a better idea.

 -- Scheme Procedure: getlogin
 -- C Function: scm_getlogin ()
     Return a string containing the name of the user logged in on the
     controlling terminal of the process, or ‘#f’ if this information
     cannot be obtained.


File: guile.info,  Node: Time,  Next: Runtime Environment,  Prev: User Information,  Up: POSIX

6.2.5 Time
----------

 -- Scheme Procedure: current-time
 -- C Function: scm_current_time ()
     Return the number of seconds since 1970-01-01 00:00:00 UTC,
     excluding leap seconds.

 -- Scheme Procedure: gettimeofday
 -- C Function: scm_gettimeofday ()
     Return a pair containing the number of seconds and microseconds
     since 1970-01-01 00:00:00 UTC, excluding leap seconds.  Note:
     whether true microsecond resolution is available depends on the
     operating system.

   The following procedures either accept an object representing a
broken down time and return a selected component, or accept an object
representing a broken down time and a value and set the component to the
value.  The numbers in parentheses give the usual range.

 -- Scheme Procedure: tm:sec tm
 -- Scheme Procedure: set-tm:sec tm val
     Seconds (0-59).
 -- Scheme Procedure: tm:min tm
 -- Scheme Procedure: set-tm:min tm val
     Minutes (0-59).
 -- Scheme Procedure: tm:hour tm
 -- Scheme Procedure: set-tm:hour tm val
     Hours (0-23).
 -- Scheme Procedure: tm:mday tm
 -- Scheme Procedure: set-tm:mday tm val
     Day of the month (1-31).
 -- Scheme Procedure: tm:mon tm
 -- Scheme Procedure: set-tm:mon tm val
     Month (0-11).
 -- Scheme Procedure: tm:year tm
 -- Scheme Procedure: set-tm:year tm val
     Year (70-), the year minus 1900.
 -- Scheme Procedure: tm:wday tm
 -- Scheme Procedure: set-tm:wday tm val
     Day of the week (0-6) with Sunday represented as 0.
 -- Scheme Procedure: tm:yday tm
 -- Scheme Procedure: set-tm:yday tm val
     Day of the year (0-364, 365 in leap years).
 -- Scheme Procedure: tm:isdst tm
 -- Scheme Procedure: set-tm:isdst tm val
     Daylight saving indicator (0 for "no", greater than 0 for "yes",
     less than 0 for "unknown").
 -- Scheme Procedure: tm:gmtoff tm
 -- Scheme Procedure: set-tm:gmtoff tm val
     Time zone offset in seconds west of UTC (-46800 to 43200).  For
     example on East coast USA (zone ‘EST+5’) this would be 18000 (ie.
     5*60*60) in winter, or 14400 (ie. 4*60*60) during daylight savings.

     Note ‘tm:gmtoff’ is not the same as ‘tm_gmtoff’ in the C ‘tm’
     structure.  ‘tm_gmtoff’ is seconds east and hence the negative of
     the value here.
 -- Scheme Procedure: tm:zone tm
 -- Scheme Procedure: set-tm:zone tm val
     Time zone label (a string), not necessarily unique.

 -- Scheme Procedure: localtime time [zone]
 -- C Function: scm_localtime (time, zone)
     Return an object representing the broken down components of TIME,
     an integer like the one returned by ‘current-time’.  The time zone
     for the calculation is optionally specified by ZONE (a string),
     otherwise the ‘TZ’ environment variable or the system default is
     used.

 -- Scheme Procedure: gmtime time
 -- C Function: scm_gmtime (time)
     Return an object representing the broken down components of TIME,
     an integer like the one returned by ‘current-time’.  The values are
     calculated for UTC.

 -- Scheme Procedure: mktime sbd-time [zone]
 -- C Function: scm_mktime (sbd_time, zone)
     For a broken down time object SBD-TIME, return a pair the ‘car’ of
     which is an integer time like ‘current-time’, and the ‘cdr’ of
     which is a new broken down time with normalized fields.

     ZONE is a timezone string, or the default is the ‘TZ’ environment
     variable or the system default (*note Specifying the Time Zone with
     ‘TZ’: (libc)TZ Variable.).  SBD-TIME is taken to be in that ZONE.

     The following fields of SBD-TIME are used: ‘tm:year’, ‘tm:mon’,
     ‘tm:mday’, ‘tm:hour’, ‘tm:min’, ‘tm:sec’, ‘tm:isdst’.  The values
     can be outside their usual ranges.  For example ‘tm:hour’ normally
     goes up to 23, but a value say 33 would mean 9 the following day.

     ‘tm:isdst’ in SBD-TIME says whether the time given is with daylight
     savings or not.  This is ignored if ZONE doesn't have any daylight
     savings adjustment amount.

     The broken down time in the return normalizes the values of
     SBD-TIME by bringing them into their usual ranges, and using the
     actual daylight savings rule for that time in ZONE (which may
     differ from what SBD-TIME had).  The easiest way to think of this
     is that SBD-TIME plus ZONE converts to the integer UTC time, then a
     ‘localtime’ is applied to get the normal presentation of that time,
     in ZONE.

 -- Scheme Procedure: tzset
 -- C Function: scm_tzset ()
     Initialize the timezone from the ‘TZ’ environment variable or the
     system default.  It's not usually necessary to call this procedure
     since it's done automatically by other procedures that depend on
     the timezone.

 -- Scheme Procedure: strftime format tm
 -- C Function: scm_strftime (format, tm)
     Return a string which is broken-down time structure TM formatted
     according to the given FORMAT string.

     FORMAT contains field specifications introduced by a ‘%’ character.
     See *note (libc)Formatting Calendar Time::, or ‘man 3 strftime’,
     for the available formatting.

          (strftime "%c" (localtime (current-time)))
          ⇒ "Mon Mar 11 20:17:43 2002"

     If ‘setlocale’ has been called (*note Locales::), month and day
     names are from the current locale and in the locale character set.

     Note that ‘%Z’ might print the ‘tm:zone’ in TM or it might print
     just the current zone (‘tzset’ above).  A GNU system prints
     ‘tm:zone’, a strict C99 system like NetBSD prints the current zone.
     Perhaps in the future Guile will try to get ‘tm:zone’ used always.

 -- Scheme Procedure: strptime format string
 -- C Function: scm_strptime (format, string)
     Performs the reverse action to ‘strftime’, parsing STRING according
     to the specification supplied in TEMPLATE.  The interpretation of
     month and day names is dependent on the current locale.  The value
     returned is a pair.  The CAR has an object with time components in
     the form returned by ‘localtime’ or ‘gmtime’, but the time zone
     components are not usefully set.  The CDR reports the number of
     characters from STRING which were used for the conversion.

 -- Variable: internal-time-units-per-second
     The value of this variable is the number of time units per second
     reported by the following procedures.

 -- Scheme Procedure: times
 -- C Function: scm_times ()
     Return an object with information about real and processor time.
     The following procedures accept such an object as an argument and
     return a selected component:

      -- Scheme Procedure: tms:clock tms
          The current real time, expressed as time units relative to an
          arbitrary base.
      -- Scheme Procedure: tms:utime tms
          The CPU time units used by the calling process.
      -- Scheme Procedure: tms:stime tms
          The CPU time units used by the system on behalf of the calling
          process.
      -- Scheme Procedure: tms:cutime tms
          The CPU time units used by terminated child processes of the
          calling process, whose status has been collected (e.g., using
          ‘waitpid’).
      -- Scheme Procedure: tms:cstime tms
          Similarly, the CPU times units used by the system on behalf of
          terminated child processes.

 -- Scheme Procedure: get-internal-real-time
 -- C Function: scm_get_internal_real_time ()
     Return the number of time units since the interpreter was started.

 -- Scheme Procedure: get-internal-run-time
 -- C Function: scm_get_internal_run_time ()
     Return the number of time units of processor time used by the
     interpreter.  Both _system_ and _user_ time are included but
     subprocesses are not.


File: guile.info,  Node: Runtime Environment,  Next: Processes,  Prev: Time,  Up: POSIX

6.2.6 Runtime Environment
-------------------------

 -- Scheme Procedure: program-arguments
 -- Scheme Procedure: command-line
 -- Scheme Procedure: set-program-arguments
 -- C Function: scm_program_arguments ()
 -- C Function: scm_set_program_arguments_scm (lst)
     Get the command line arguments passed to Guile, or set new
     arguments.

     The arguments are a list of strings, the first of which is the
     invoked program name.  This is just "guile" (or the executable
     path) when run interactively, or it's the script name when running
     a script with ‘-s’ (*note Invoking Guile::).

          guile -L /my/extra/dir -s foo.scm abc def

          (program-arguments) ⇒ ("foo.scm" "abc" "def")

     ‘set-program-arguments’ allows a library module or similar to
     modify the arguments, for example to strip options it recognises,
     leaving the rest for the mainline.

     The argument list is held in a fluid, which means it's separate for
     each thread.  Neither the list nor the strings within it are copied
     at any point and normally should not be mutated.

     The two names ‘program-arguments’ and ‘command-line’ are an
     historical accident, they both do exactly the same thing.  The name
     ‘scm_set_program_arguments_scm’ has an extra ‘_scm’ on the end to
     avoid clashing with the C function below.

 -- C Function: void scm_set_program_arguments (int argc, char **argv,
          char *first)
     Set the list of command line arguments for ‘program-arguments’ and
     ‘command-line’ above.

     ARGV is an array of null-terminated strings, as in a C ‘main’
     function.  ARGC is the number of strings in ARGV, or if it's
     negative then a ‘NULL’ in ARGV marks its end.

     FIRST is an extra string put at the start of the arguments, or
     ‘NULL’ for no such extra.  This is a convenient way to pass the
     program name after advancing ARGV to strip option arguments.  Eg.

          {
            char *progname = argv[0];
            for (argv++; argv[0] != NULL && argv[0][0] == '-'; argv++)
              {
                /* munch option ... */
              }
            /* remaining args for scheme level use */
            scm_set_program_arguments (-1, argv, progname);
          }

     This sort of thing is often done at startup under ‘scm_boot_guile’
     with options handled at the C level removed.  The given strings are
     all copied, so the C data is not accessed again once
     ‘scm_set_program_arguments’ returns.

 -- Scheme Procedure: getenv nam
 -- C Function: scm_getenv (nam)
     Looks up the string NAME in the current environment.  The return
     value is ‘#f’ unless a string of the form ‘NAME=VALUE’ is found, in
     which case the string ‘VALUE’ is returned.

 -- Scheme Procedure: setenv name value
     Modifies the environment of the current process, which is also the
     default environment inherited by child processes.

     If VALUE is ‘#f’, then NAME is removed from the environment.
     Otherwise, the string NAME=VALUE is added to the environment,
     replacing any existing string with name matching NAME.

     The return value is unspecified.

 -- Scheme Procedure: unsetenv name
     Remove variable NAME from the environment.  The name can not
     contain a ‘=’ character.

 -- Scheme Procedure: environ [env]
 -- C Function: scm_environ (env)
     If ENV is omitted, return the current environment (in the Unix
     sense) as a list of strings.  Otherwise set the current
     environment, which is also the default environment for child
     processes, to the supplied list of strings.  Each member of ENV
     should be of the form NAME=VALUE and values of NAME should not be
     duplicated.  If ENV is supplied then the return value is
     unspecified.

 -- Scheme Procedure: putenv str
 -- C Function: scm_putenv (str)
     Modifies the environment of the current process, which is also the
     default environment inherited by child processes.

     If STRING is of the form ‘NAME=VALUE’ then it will be written
     directly into the environment, replacing any existing environment
     string with name matching ‘NAME’.  If STRING does not contain an
     equal sign, then any existing string with name matching STRING will
     be removed.

     The return value is unspecified.


File: guile.info,  Node: Processes,  Next: Signals,  Prev: Runtime Environment,  Up: POSIX

6.2.7 Processes
---------------

 -- Scheme Procedure: chdir str
 -- C Function: scm_chdir (str)
     Change the current working directory to PATH.  The return value is
     unspecified.

 -- Scheme Procedure: getcwd
 -- C Function: scm_getcwd ()
     Return the name of the current working directory.

 -- Scheme Procedure: umask [mode]
 -- C Function: scm_umask (mode)
     If MODE is omitted, returns a decimal number representing the
     current file creation mask.  Otherwise the file creation mask is
     set to MODE and the previous value is returned.  *Note Assigning
     File Permissions: (libc)Setting Permissions, for more on how to use
     umasks.

     E.g., ‘(umask #o022)’ sets the mask to octal 22/decimal 18.

 -- Scheme Procedure: chroot path
 -- C Function: scm_chroot (path)
     Change the root directory to that specified in PATH.  This
     directory will be used for path names beginning with ‘/’.  The root
     directory is inherited by all children of the current process.
     Only the superuser may change the root directory.

 -- Scheme Procedure: getpid
 -- C Function: scm_getpid ()
     Return an integer representing the current process ID.

 -- Scheme Procedure: getgroups
 -- C Function: scm_getgroups ()
     Return a vector of integers representing the current supplementary
     group IDs.

 -- Scheme Procedure: getppid
 -- C Function: scm_getppid ()
     Return an integer representing the process ID of the parent
     process.

 -- Scheme Procedure: getuid
 -- C Function: scm_getuid ()
     Return an integer representing the current real user ID.

 -- Scheme Procedure: getgid
 -- C Function: scm_getgid ()
     Return an integer representing the current real group ID.

 -- Scheme Procedure: geteuid
 -- C Function: scm_geteuid ()
     Return an integer representing the current effective user ID. If
     the system does not support effective IDs, then the real ID is
     returned.  ‘(provided? 'EIDs)’ reports whether the system supports
     effective IDs.

 -- Scheme Procedure: getegid
 -- C Function: scm_getegid ()
     Return an integer representing the current effective group ID. If
     the system does not support effective IDs, then the real ID is
     returned.  ‘(provided? 'EIDs)’ reports whether the system supports
     effective IDs.

 -- Scheme Procedure: setgroups vec
 -- C Function: scm_setgroups (vec)
     Set the current set of supplementary group IDs to the integers in
     the given vector VEC.  The return value is unspecified.

     Generally only the superuser can set the process group IDs (*note
     Setting the Group IDs: (libc)Setting Groups.).

 -- Scheme Procedure: setuid id
 -- C Function: scm_setuid (id)
     Sets both the real and effective user IDs to the integer ID,
     provided the process has appropriate privileges.  The return value
     is unspecified.

 -- Scheme Procedure: setgid id
 -- C Function: scm_setgid (id)
     Sets both the real and effective group IDs to the integer ID,
     provided the process has appropriate privileges.  The return value
     is unspecified.

 -- Scheme Procedure: seteuid id
 -- C Function: scm_seteuid (id)
     Sets the effective user ID to the integer ID, provided the process
     has appropriate privileges.  If effective IDs are not supported,
     the real ID is set instead--‘(provided? 'EIDs)’ reports whether the
     system supports effective IDs.  The return value is unspecified.

 -- Scheme Procedure: setegid id
 -- C Function: scm_setegid (id)
     Sets the effective group ID to the integer ID, provided the process
     has appropriate privileges.  If effective IDs are not supported,
     the real ID is set instead--‘(provided? 'EIDs)’ reports whether the
     system supports effective IDs.  The return value is unspecified.

 -- Scheme Procedure: getpgrp
 -- C Function: scm_getpgrp ()
     Return an integer representing the current process group ID. This
     is the POSIX definition, not BSD.

 -- Scheme Procedure: setpgid pid pgid
 -- C Function: scm_setpgid (pid, pgid)
     Move the process PID into the process group PGID.  PID or PGID must
     be integers: they can be zero to indicate the ID of the current
     process.  Fails on systems that do not support job control.  The
     return value is unspecified.

 -- Scheme Procedure: setsid
 -- C Function: scm_setsid ()
     Creates a new session.  The current process becomes the session
     leader and is put in a new process group.  The process will be
     detached from its controlling terminal if it has one.  The return
     value is an integer representing the new process group ID.

 -- Scheme Procedure: waitpid pid [options]
 -- C Function: scm_waitpid (pid, options)
     This procedure collects status information from a child process
     which has terminated or (optionally) stopped.  Normally it will
     suspend the calling process until this can be done.  If more than
     one child process is eligible then one will be chosen by the
     operating system.

     The value of PID determines the behaviour:

     PID greater than 0
          Request status information from the specified child process.
     PID equal to -1 or ‘WAIT_ANY’
          Request status information for any child process.
     PID equal to 0 or ‘WAIT_MYPGRP’
          Request status information for any child process in the
          current process group.
     PID less than -1
          Request status information for any child process whose process
          group ID is −PID.

     The OPTIONS argument, if supplied, should be the bitwise OR of the
     values of zero or more of the following variables:

      -- Variable: WNOHANG
          Return immediately even if there are no child processes to be
          collected.

      -- Variable: WUNTRACED
          Report status information for stopped processes as well as
          terminated processes.

     The return value is a pair containing:

       1. The process ID of the child process, or 0 if ‘WNOHANG’ was
          specified and no process was collected.
       2. The integer status value.

   The following three functions can be used to decode the process
status code returned by ‘waitpid’.

 -- Scheme Procedure: status:exit-val status
 -- C Function: scm_status_exit_val (status)
     Return the exit status value, as would be set if a process ended
     normally through a call to ‘exit’ or ‘_exit’, if any, otherwise
     ‘#f’.

 -- Scheme Procedure: status:term-sig status
 -- C Function: scm_status_term_sig (status)
     Return the signal number which terminated the process, if any,
     otherwise ‘#f’.

 -- Scheme Procedure: status:stop-sig status
 -- C Function: scm_status_stop_sig (status)
     Return the signal number which stopped the process, if any,
     otherwise ‘#f’.

 -- Scheme Procedure: system [cmd]
 -- C Function: scm_system (cmd)
     Execute CMD using the operating system's "command processor".
     Under Unix this is usually the default shell ‘sh’.  The value
     returned is CMD's exit status as returned by ‘waitpid’, which can
     be interpreted using the functions above.

     If ‘system’ is called without arguments, return a boolean
     indicating whether the command processor is available.

 -- Scheme Procedure: system* . args
 -- C Function: scm_system_star (args)
     Execute the command indicated by ARGS.  The first element must be a
     string indicating the command to be executed, and the remaining
     items must be strings representing each of the arguments to that
     command.

     This function returns the exit status of the command as provided by
     ‘waitpid’.  This value can be handled with ‘status:exit-val’ and
     the related functions.

     ‘system*’ is similar to ‘system’, but accepts only one string
     per-argument, and performs no shell interpretation.  The command is
     executed using fork and execlp.  Accordingly this function may be
     safer than ‘system’ in situations where shell interpretation is not
     required.

     Example: (system* "echo" "foo" "bar")

 -- Scheme Procedure: primitive-exit [status]
 -- Scheme Procedure: primitive-_exit [status]
 -- C Function: scm_primitive_exit (status)
 -- C Function: scm_primitive__exit (status)
     Terminate the current process without unwinding the Scheme stack.
     The exit status is STATUS if supplied, otherwise zero.

     ‘primitive-exit’ uses the C ‘exit’ function and hence runs usual C
     level cleanups (flush output streams, call ‘atexit’ functions, etc,
     see *note (libc)Normal Termination::)).

     ‘primitive-_exit’ is the ‘_exit’ system call (*note
     (libc)Termination Internals::).  This terminates the program
     immediately, with neither Scheme-level nor C-level cleanups.

     The typical use for ‘primitive-_exit’ is from a child process
     created with ‘primitive-fork’.  For example in a Gdk program the
     child process inherits the X server connection and a C-level
     ‘atexit’ cleanup which will close that connection.  But closing in
     the child would upset the protocol in the parent, so
     ‘primitive-_exit’ should be used to exit without that.

 -- Scheme Procedure: execl filename . args
 -- C Function: scm_execl (filename, args)
     Executes the file named by PATH as a new process image.  The
     remaining arguments are supplied to the process; from a C program
     they are accessible as the ‘argv’ argument to ‘main’.
     Conventionally the first ARG is the same as PATH.  All arguments
     must be strings.

     If ARG is missing, PATH is executed with a null argument list,
     which may have system-dependent side-effects.

     This procedure is currently implemented using the ‘execv’ system
     call, but we call it ‘execl’ because of its Scheme calling
     interface.

 -- Scheme Procedure: execlp filename . args
 -- C Function: scm_execlp (filename, args)
     Similar to ‘execl’, however if FILENAME does not contain a slash
     then the file to execute will be located by searching the
     directories listed in the ‘PATH’ environment variable.

     This procedure is currently implemented using the ‘execvp’ system
     call, but we call it ‘execlp’ because of its Scheme calling
     interface.

 -- Scheme Procedure: execle filename env . args
 -- C Function: scm_execle (filename, env, args)
     Similar to ‘execl’, but the environment of the new process is
     specified by ENV, which must be a list of strings as returned by
     the ‘environ’ procedure.

     This procedure is currently implemented using the ‘execve’ system
     call, but we call it ‘execle’ because of its Scheme calling
     interface.

 -- Scheme Procedure: primitive-fork
 -- C Function: scm_fork ()
     Creates a new "child" process by duplicating the current "parent"
     process.  In the child the return value is 0.  In the parent the
     return value is the integer process ID of the child.

     This procedure has been renamed from ‘fork’ to avoid a naming
     conflict with the scsh fork.

 -- Scheme Procedure: nice incr
 -- C Function: scm_nice (incr)
     Increment the priority of the current process by INCR.  A higher
     priority value means that the process runs less often.  The return
     value is unspecified.

 -- Scheme Procedure: setpriority which who prio
 -- C Function: scm_setpriority (which, who, prio)
     Set the scheduling priority of the process, process group or user,
     as indicated by WHICH and WHO.  WHICH is one of the variables
     ‘PRIO_PROCESS’, ‘PRIO_PGRP’ or ‘PRIO_USER’, and WHO is interpreted
     relative to WHICH (a process identifier for ‘PRIO_PROCESS’, process
     group identifier for ‘PRIO_PGRP’, and a user identifier for
     ‘PRIO_USER’.  A zero value of WHO denotes the current process,
     process group, or user.  PRIO is a value in the range [−20,20].
     The default priority is 0; lower priorities (in numerical terms)
     cause more favorable scheduling.  Sets the priority of all of the
     specified processes.  Only the super-user may lower priorities.
     The return value is not specified.

 -- Scheme Procedure: getpriority which who
 -- C Function: scm_getpriority (which, who)
     Return the scheduling priority of the process, process group or
     user, as indicated by WHICH and WHO.  WHICH is one of the variables
     ‘PRIO_PROCESS’, ‘PRIO_PGRP’ or ‘PRIO_USER’, and WHO should be
     interpreted depending on WHICH (a process identifier for
     ‘PRIO_PROCESS’, process group identifier for ‘PRIO_PGRP’, and a
     user identifier for ‘PRIO_USER’).  A zero value of WHO denotes the
     current process, process group, or user.  Return the highest
     priority (lowest numerical value) of any of the specified
     processes.


File: guile.info,  Node: Signals,  Next: Terminals and Ptys,  Prev: Processes,  Up: POSIX

6.2.8 Signals
-------------

The following procedures raise, handle and wait for signals.

   Scheme code signal handlers are run via a system async (*note System
asyncs::), so they're called in the handler's thread at the next safe
opportunity.  Generally this is after any currently executing primitive
procedure finishes (which could be a long time for primitives that wait
for an external event).

 -- Scheme Procedure: kill pid sig
 -- C Function: scm_kill (pid, sig)
     Sends a signal to the specified process or group of processes.

     PID specifies the processes to which the signal is sent:

     PID greater than 0
          The process whose identifier is PID.
     PID equal to 0
          All processes in the current process group.
     PID less than -1
          The process group whose identifier is -PID
     PID equal to -1
          If the process is privileged, all processes except for some
          special system processes.  Otherwise, all processes with the
          current effective user ID.

     SIG should be specified using a variable corresponding to the Unix
     symbolic name, e.g.,

      -- Variable: SIGHUP
          Hang-up signal.

      -- Variable: SIGINT
          Interrupt signal.

     A full list of signals on the GNU system may be found in *note
     (libc)Standard Signals::.

 -- Scheme Procedure: raise sig
 -- C Function: scm_raise (sig)
     Sends a specified signal SIG to the current process, where SIG is
     as described for the ‘kill’ procedure.

 -- Scheme Procedure: sigaction signum [handler [flags [thread]]]
 -- C Function: scm_sigaction (signum, handler, flags)
 -- C Function: scm_sigaction_for_thread (signum, handler, flags,
          thread)
     Install or report the signal handler for a specified signal.

     SIGNUM is the signal number, which can be specified using the value
     of variables such as ‘SIGINT’.

     If HANDLER is omitted, ‘sigaction’ returns a pair: the CAR is the
     current signal hander, which will be either an integer with the
     value ‘SIG_DFL’ (default action) or ‘SIG_IGN’ (ignore), or the
     Scheme procedure which handles the signal, or ‘#f’ if a non-Scheme
     procedure handles the signal.  The CDR contains the current
     ‘sigaction’ flags for the handler.

     If HANDLER is provided, it is installed as the new handler for
     SIGNUM.  HANDLER can be a Scheme procedure taking one argument, or
     the value of ‘SIG_DFL’ (default action) or ‘SIG_IGN’ (ignore), or
     ‘#f’ to restore whatever signal handler was installed before
     ‘sigaction’ was first used.  When a scheme procedure has been
     specified, that procedure will run in the given THREAD.  When no
     thread has been given, the thread that made this call to
     ‘sigaction’ is used.

     FLAGS is a ‘logior’ (*note Bitwise Operations::) of the following
     (where provided by the system), or ‘0’ for none.

      -- Variable: SA_NOCLDSTOP
          By default, ‘SIGCHLD’ is signalled when a child process stops
          (ie. receives ‘SIGSTOP’), and when a child process terminates.
          With the ‘SA_NOCLDSTOP’ flag, ‘SIGCHLD’ is only signalled for
          termination, not stopping.

          ‘SA_NOCLDSTOP’ has no effect on signals other than ‘SIGCHLD’.

      -- Variable: SA_RESTART
          If a signal occurs while in a system call, deliver the signal
          then restart the system call (as opposed to returning an
          ‘EINTR’ error from that call).

     The return value is a pair with information about the old handler
     as described above.

     This interface does not provide access to the "signal blocking"
     facility.  Maybe this is not needed, since the thread support may
     provide solutions to the problem of consistent access to data
     structures.

 -- Scheme Procedure: restore-signals
 -- C Function: scm_restore_signals ()
     Return all signal handlers to the values they had before any call
     to ‘sigaction’ was made.  The return value is unspecified.

 -- Scheme Procedure: alarm i
 -- C Function: scm_alarm (i)
     Set a timer to raise a ‘SIGALRM’ signal after the specified number
     of seconds (an integer).  It's advisable to install a signal
     handler for ‘SIGALRM’ beforehand, since the default action is to
     terminate the process.

     The return value indicates the time remaining for the previous
     alarm, if any.  The new value replaces the previous alarm.  If
     there was no previous alarm, the return value is zero.

 -- Scheme Procedure: pause
 -- C Function: scm_pause ()
     Pause the current process (thread?)  until a signal arrives whose
     action is to either terminate the current process or invoke a
     handler procedure.  The return value is unspecified.

 -- Scheme Procedure: sleep secs
 -- Scheme Procedure: usleep usecs
 -- C Function: scm_sleep (secs)
 -- C Function: scm_usleep (usecs)
     Wait the given period SECS seconds or USECS microseconds (both
     integers).  If a signal arrives the wait stops and the return value
     is the time remaining, in seconds or microseconds respectively.  If
     the period elapses with no signal the return is zero.

     On most systems the process scheduler is not microsecond accurate
     and the actual period slept by ‘usleep’ might be rounded to a
     system clock tick boundary, which might be 10 milliseconds for
     instance.

     See ‘scm_std_sleep’ and ‘scm_std_usleep’ for equivalents at the C
     level (*note Blocking::).

 -- Scheme Procedure: getitimer which_timer
 -- Scheme Procedure: setitimer which_timer interval_seconds
          interval_microseconds periodic_seconds periodic_microseconds
 -- C Function: scm_getitimer (which_timer)
 -- C Function: scm_setitimer (which_timer, interval_seconds,
          interval_microseconds, periodic_seconds,
          periodic_microseconds)
     Get or set the periods programmed in certain system timers.  These
     timers have a current interval value which counts down and on
     reaching zero raises a signal.  An optional periodic value can be
     set to restart from there each time, for periodic operation.
     WHICH_TIMER is one of the following values

      -- Variable: ITIMER_REAL
          A real-time timer, counting down elapsed real time.  At zero
          it raises ‘SIGALRM’.  This is like ‘alarm’ above, but with a
          higher resolution period.

      -- Variable: ITIMER_VIRTUAL
          A virtual-time timer, counting down while the current process
          is actually using CPU. At zero it raises ‘SIGVTALRM’.

      -- Variable: ITIMER_PROF
          A profiling timer, counting down while the process is running
          (like ‘ITIMER_VIRTUAL’) and also while system calls are
          running on the process's behalf.  At zero it raises a
          ‘SIGPROF’.

          This timer is intended for profiling where a program is
          spending its time (by looking where it is when the timer goes
          off).

     ‘getitimer’ returns the current timer value and its programmed
     restart value, as a list containing two pairs.  Each pair is a time
     in seconds and microseconds: ‘((INTERVAL_SECS . INTERVAL_USECS)
     (PERIODIC_SECS . PERIODIC_USECS))’.

     ‘setitimer’ sets the timer values similarly, in seconds and
     microseconds (which must be integers).  The periodic value can be
     zero to have the timer run down just once.  The return value is the
     timer's previous setting, in the same form as ‘getitimer’ returns.

          (setitimer ITIMER_REAL
                     5 500000     ;; first SIGALRM in 5.5 seconds time
                     2 0)         ;; then repeat every 2 seconds

     Although the timers are programmed in microseconds, the actual
     accuracy might not be that high.


File: guile.info,  Node: Terminals and Ptys,  Next: Pipes,  Prev: Signals,  Up: POSIX

6.2.9 Terminals and Ptys
------------------------

 -- Scheme Procedure: isatty? port
 -- C Function: scm_isatty_p (port)
     Return ‘#t’ if PORT is using a serial non-file device, otherwise
     ‘#f’.

 -- Scheme Procedure: ttyname port
 -- C Function: scm_ttyname (port)
     Return a string with the name of the serial terminal device
     underlying PORT.

 -- Scheme Procedure: ctermid
 -- C Function: scm_ctermid ()
     Return a string containing the file name of the controlling
     terminal for the current process.

 -- Scheme Procedure: tcgetpgrp port
 -- C Function: scm_tcgetpgrp (port)
     Return the process group ID of the foreground process group
     associated with the terminal open on the file descriptor underlying
     PORT.

     If there is no foreground process group, the return value is a
     number greater than 1 that does not match the process group ID of
     any existing process group.  This can happen if all of the
     processes in the job that was formerly the foreground job have
     terminated, and no other job has yet been moved into the
     foreground.

 -- Scheme Procedure: tcsetpgrp port pgid
 -- C Function: scm_tcsetpgrp (port, pgid)
     Set the foreground process group ID for the terminal used by the
     file descriptor underlying PORT to the integer PGID.  The calling
     process must be a member of the same session as PGID and must have
     the same controlling terminal.  The return value is unspecified.


File: guile.info,  Node: Pipes,  Next: Networking,  Prev: Terminals and Ptys,  Up: POSIX

6.2.10 Pipes
------------

The following procedures are similar to the ‘popen’ and ‘pclose’ system
routines.  The code is in a separate "popen" module:

     (use-modules (ice-9 popen))

 -- Scheme Procedure: open-pipe command mode
 -- Scheme Procedure: open-pipe* mode prog [args...]
     Execute a command in a subprocess, with a pipe to it or from it, or
     with pipes in both directions.

     ‘open-pipe’ runs the shell COMMAND using ‘/bin/sh -c’.
     ‘open-pipe*’ executes PROG directly, with the optional ARGS
     arguments (all strings).

     MODE should be one of the following values.  ‘OPEN_READ’ is an
     input pipe, ie. to read from the subprocess.  ‘OPEN_WRITE’ is an
     output pipe, ie. to write to it.

      -- Variable: OPEN_READ
      -- Variable: OPEN_WRITE
      -- Variable: OPEN_BOTH

     For an input pipe, the child's standard output is the pipe and
     standard input is inherited from ‘current-input-port’.  For an
     output pipe, the child's standard input is the pipe and standard
     output is inherited from ‘current-output-port’.  In all cases cases
     the child's standard error is inherited from ‘current-error-port’
     (*note Default Ports::).

     If those ‘current-X-ports’ are not files of some kind, and hence
     don't have file descriptors for the child, then ‘/dev/null’ is used
     instead.

     Care should be taken with ‘OPEN_BOTH’, a deadlock will occur if
     both parent and child are writing, and waiting until the write
     completes before doing any reading.  Each direction has ‘PIPE_BUF’
     bytes of buffering (*note Ports and File Descriptors::), which will
     be enough for small writes, but not for say putting a big file
     through a filter.

 -- Scheme Procedure: open-input-pipe command
     Equivalent to ‘open-pipe’ with mode ‘OPEN_READ’.

          (let* ((port (open-input-pipe "date --utc"))
                 (str  (read-line port)))
            (close-pipe port)
            str)
          ⇒ "Mon Mar 11 20:10:44 UTC 2002"

 -- Scheme Procedure: open-output-pipe command
     Equivalent to ‘open-pipe’ with mode ‘OPEN_WRITE’.

          (let ((port (open-output-pipe "lpr")))
            (display "Something for the line printer.\n" port)
            (if (not (eqv? 0 (status:exit-val (close-pipe port))))
                (error "Cannot print")))

 -- Scheme Procedure: open-input-output-pipe command
     Equivalent to ‘open-pipe’ with mode ‘OPEN_BOTH’.

 -- Scheme Procedure: close-pipe port
     Close a pipe created by ‘open-pipe’, wait for the process to
     terminate, and return the wait status code.  The status is as per
     ‘waitpid’ and can be decoded with ‘status:exit-val’ etc (*note
     Processes::)


   ‘waitpid WAIT_ANY’ should not be used when pipes are open, since it
can reap a pipe's child process, causing an error from a subsequent
‘close-pipe’.

   ‘close-port’ (*note Closing::) can close a pipe, but it doesn't reap
the child process.

   The garbage collector will close a pipe no longer in use, and reap
the child process with ‘waitpid’.  If the child hasn't yet terminated
the garbage collector doesn't block, but instead checks again in the
next GC.

   Many systems have per-user and system-wide limits on the number of
processes, and a system-wide limit on the number of pipes, so pipes
should be closed explicitly when no longer needed, rather than letting
the garbage collector pick them up at some later time.


File: guile.info,  Node: Networking,  Next: System Identification,  Prev: Pipes,  Up: POSIX

6.2.11 Networking
-----------------

* Menu:

* Network Address Conversion::
* Network Databases::
* Network Socket Address::
* Network Sockets and Communication::
* Internet Socket Examples::


File: guile.info,  Node: Network Address Conversion,  Next: Network Databases,  Up: Networking

6.2.11.1 Network Address Conversion
...................................

This section describes procedures which convert internet addresses
between numeric and string formats.

IPv4 Address Conversion
.......................

An IPv4 Internet address is a 4-byte value, represented in Guile as an
integer in host byte order, so that say "0.0.0.1" is 1, or "1.0.0.0" is
16777216.

   Some underlying C functions use network byte order for addresses,
Guile converts as necessary so that at the Scheme level its host byte
order everywhere.

 -- Variable: INADDR_ANY
     For a server, this can be used with ‘bind’ (*note Network Sockets
     and Communication::) to allow connections from any interface on the
     machine.

 -- Variable: INADDR_BROADCAST
     The broadcast address on the local network.

 -- Variable: INADDR_LOOPBACK
     The address of the local host using the loopback device, ie.
     ‘127.0.0.1’.

 -- Scheme Procedure: inet-aton address
 -- C Function: scm_inet_aton (address)
     Convert an IPv4 Internet address from printable string (dotted
     decimal notation) to an integer.  E.g.,

          (inet-aton "127.0.0.1") ⇒ 2130706433

 -- Scheme Procedure: inet-ntoa inetid
 -- C Function: scm_inet_ntoa (inetid)
     Convert an IPv4 Internet address to a printable (dotted decimal
     notation) string.  E.g.,

          (inet-ntoa 2130706433) ⇒ "127.0.0.1"

 -- Scheme Procedure: inet-netof address
 -- C Function: scm_inet_netof (address)
     Return the network number part of the given IPv4 Internet address.
     E.g.,

          (inet-netof 2130706433) ⇒ 127

 -- Scheme Procedure: inet-lnaof address
 -- C Function: scm_lnaof (address)
     Return the local-address-with-network part of the given IPv4
     Internet address, using the obsolete class A/B/C system.  E.g.,

          (inet-lnaof 2130706433) ⇒ 1

 -- Scheme Procedure: inet-makeaddr net lna
 -- C Function: scm_inet_makeaddr (net, lna)
     Make an IPv4 Internet address by combining the network number NET
     with the local-address-within-network number LNA.  E.g.,

          (inet-makeaddr 127 1) ⇒ 2130706433

IPv6 Address Conversion
.......................

An IPv6 Internet address is a 16-byte value, represented in Guile as an
integer in host byte order, so that say "::1" is 1.

 -- Scheme Procedure: inet-ntop family address
 -- C Function: scm_inet_ntop (family, address)
     Convert a network address from an integer to a printable string.
     FAMILY can be ‘AF_INET’ or ‘AF_INET6’.  E.g.,

          (inet-ntop AF_INET 2130706433) ⇒ "127.0.0.1"
          (inet-ntop AF_INET6 (- (expt 2 128) 1))
            ⇒ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"

 -- Scheme Procedure: inet-pton family address
 -- C Function: scm_inet_pton (family, address)
     Convert a string containing a printable network address to an
     integer address.  FAMILY can be ‘AF_INET’ or ‘AF_INET6’.  E.g.,

          (inet-pton AF_INET "127.0.0.1") ⇒ 2130706433
          (inet-pton AF_INET6 "::1") ⇒ 1


File: guile.info,  Node: Network Databases,  Next: Network Socket Address,  Prev: Network Address Conversion,  Up: Networking

6.2.11.2 Network Databases
..........................

This section describes procedures which query various network databases.
Care should be taken when using the database routines since they are not
reentrant.

The Host Database
.................

A “host object” is a structure that represents what is known about a
network host, and is the usual way of representing a system's network
identity inside software.

   The following functions accept a host object and return a selected
component:

 -- Scheme Procedure: hostent:name host
     The "official" hostname for HOST.
 -- Scheme Procedure: hostent:aliases host
     A list of aliases for HOST.
 -- Scheme Procedure: hostent:addrtype host
     The host address type, one of the ‘AF’ constants, such as ‘AF_INET’
     or ‘AF_INET6’.
 -- Scheme Procedure: hostent:length host
     The length of each address for HOST, in bytes.
 -- Scheme Procedure: hostent:addr-list host
     The list of network addresses associated with HOST.  For ‘AF_INET’
     these are integer IPv4 address (*note Network Address
     Conversion::).

   The following procedures are used to search the host database:

 -- Scheme Procedure: gethost [host]
 -- Scheme Procedure: gethostbyname hostname
 -- Scheme Procedure: gethostbyaddr address
 -- C Function: scm_gethost (host)
     Look up a host by name or address, returning a host object.  The
     ‘gethost’ procedure will accept either a string name or an integer
     address; if given no arguments, it behaves like ‘gethostent’ (see
     below).  If a name or address is supplied but the address can not
     be found, an error will be thrown to one of the keys:
     ‘host-not-found’, ‘try-again’, ‘no-recovery’ or ‘no-data’,
     corresponding to the equivalent ‘h_error’ values.  Unusual
     conditions may result in errors thrown to the ‘system-error’ or
     ‘misc_error’ keys.

          (gethost "www.gnu.org")
          ⇒ #("www.gnu.org" () 2 4 (3353880842))

          (gethostbyname "www.emacs.org")
          ⇒ #("emacs.org" ("www.emacs.org") 2 4 (1073448978))

   The following procedures may be used to step through the host
database from beginning to end.

 -- Scheme Procedure: sethostent [stayopen]
     Initialize an internal stream from which host objects may be read.
     This procedure must be called before any calls to ‘gethostent’, and
     may also be called afterward to reset the host entry stream.  If
     STAYOPEN is supplied and is not ‘#f’, the database is not closed by
     subsequent ‘gethostbyname’ or ‘gethostbyaddr’ calls, possibly
     giving an efficiency gain.

 -- Scheme Procedure: gethostent
     Return the next host object from the host database, or ‘#f’ if
     there are no more hosts to be found (or an error has been
     encountered).  This procedure may not be used before ‘sethostent’
     has been called.

 -- Scheme Procedure: endhostent
     Close the stream used by ‘gethostent’.  The return value is
     unspecified.

 -- Scheme Procedure: sethost [stayopen]
 -- C Function: scm_sethost (stayopen)
     If STAYOPEN is omitted, this is equivalent to ‘endhostent’.
     Otherwise it is equivalent to ‘sethostent stayopen’.

The Network Database
....................

The following functions accept an object representing a network and
return a selected component:

 -- Scheme Procedure: netent:name net
     The "official" network name.
 -- Scheme Procedure: netent:aliases net
     A list of aliases for the network.
 -- Scheme Procedure: netent:addrtype net
     The type of the network number.  Currently, this returns only
     ‘AF_INET’.
 -- Scheme Procedure: netent:net net
     The network number.

   The following procedures are used to search the network database:

 -- Scheme Procedure: getnet [net]
 -- Scheme Procedure: getnetbyname net-name
 -- Scheme Procedure: getnetbyaddr net-number
 -- C Function: scm_getnet (net)
     Look up a network by name or net number in the network database.
     The NET-NAME argument must be a string, and the NET-NUMBER argument
     must be an integer.  ‘getnet’ will accept either type of argument,
     behaving like ‘getnetent’ (see below) if no arguments are given.

   The following procedures may be used to step through the network
database from beginning to end.

 -- Scheme Procedure: setnetent [stayopen]
     Initialize an internal stream from which network objects may be
     read.  This procedure must be called before any calls to
     ‘getnetent’, and may also be called afterward to reset the net
     entry stream.  If STAYOPEN is supplied and is not ‘#f’, the
     database is not closed by subsequent ‘getnetbyname’ or
     ‘getnetbyaddr’ calls, possibly giving an efficiency gain.

 -- Scheme Procedure: getnetent
     Return the next entry from the network database.

 -- Scheme Procedure: endnetent
     Close the stream used by ‘getnetent’.  The return value is
     unspecified.

 -- Scheme Procedure: setnet [stayopen]
 -- C Function: scm_setnet (stayopen)
     If STAYOPEN is omitted, this is equivalent to ‘endnetent’.
     Otherwise it is equivalent to ‘setnetent stayopen’.

The Protocol Database
.....................

The following functions accept an object representing a protocol and
return a selected component:

 -- Scheme Procedure: protoent:name protocol
     The "official" protocol name.
 -- Scheme Procedure: protoent:aliases protocol
     A list of aliases for the protocol.
 -- Scheme Procedure: protoent:proto protocol
     The protocol number.

   The following procedures are used to search the protocol database:

 -- Scheme Procedure: getproto [protocol]
 -- Scheme Procedure: getprotobyname name
 -- Scheme Procedure: getprotobynumber number
 -- C Function: scm_getproto (protocol)
     Look up a network protocol by name or by number.  ‘getprotobyname’
     takes a string argument, and ‘getprotobynumber’ takes an integer
     argument.  ‘getproto’ will accept either type, behaving like
     ‘getprotoent’ (see below) if no arguments are supplied.

   The following procedures may be used to step through the protocol
database from beginning to end.

 -- Scheme Procedure: setprotoent [stayopen]
     Initialize an internal stream from which protocol objects may be
     read.  This procedure must be called before any calls to
     ‘getprotoent’, and may also be called afterward to reset the
     protocol entry stream.  If STAYOPEN is supplied and is not ‘#f’,
     the database is not closed by subsequent ‘getprotobyname’ or
     ‘getprotobynumber’ calls, possibly giving an efficiency gain.

 -- Scheme Procedure: getprotoent
     Return the next entry from the protocol database.

 -- Scheme Procedure: endprotoent
     Close the stream used by ‘getprotoent’.  The return value is
     unspecified.

 -- Scheme Procedure: setproto [stayopen]
 -- C Function: scm_setproto (stayopen)
     If STAYOPEN is omitted, this is equivalent to ‘endprotoent’.
     Otherwise it is equivalent to ‘setprotoent stayopen’.

The Service Database
....................

The following functions accept an object representing a service and
return a selected component:

 -- Scheme Procedure: servent:name serv
     The "official" name of the network service.
 -- Scheme Procedure: servent:aliases serv
     A list of aliases for the network service.
 -- Scheme Procedure: servent:port serv
     The Internet port used by the service.
 -- Scheme Procedure: servent:proto serv
     The protocol used by the service.  A service may be listed many
     times in the database under different protocol names.

   The following procedures are used to search the service database:

 -- Scheme Procedure: getserv [name [protocol]]
 -- Scheme Procedure: getservbyname name protocol
 -- Scheme Procedure: getservbyport port protocol
 -- C Function: scm_getserv (name, protocol)
     Look up a network service by name or by service number, and return
     a network service object.  The PROTOCOL argument specifies the name
     of the desired protocol; if the protocol found in the network
     service database does not match this name, a system error is
     signalled.

     The ‘getserv’ procedure will take either a service name or number
     as its first argument; if given no arguments, it behaves like
     ‘getservent’ (see below).

          (getserv "imap" "tcp")
          ⇒ #("imap2" ("imap") 143 "tcp")

          (getservbyport 88 "udp")
          ⇒ #("kerberos" ("kerberos5" "krb5") 88 "udp")

   The following procedures may be used to step through the service
database from beginning to end.

 -- Scheme Procedure: setservent [stayopen]
     Initialize an internal stream from which service objects may be
     read.  This procedure must be called before any calls to
     ‘getservent’, and may also be called afterward to reset the service
     entry stream.  If STAYOPEN is supplied and is not ‘#f’, the
     database is not closed by subsequent ‘getservbyname’ or
     ‘getservbyport’ calls, possibly giving an efficiency gain.

 -- Scheme Procedure: getservent
     Return the next entry from the services database.

 -- Scheme Procedure: endservent
     Close the stream used by ‘getservent’.  The return value is
     unspecified.

 -- Scheme Procedure: setserv [stayopen]
 -- C Function: scm_setserv (stayopen)
     If STAYOPEN is omitted, this is equivalent to ‘endservent’.
     Otherwise it is equivalent to ‘setservent stayopen’.


File: guile.info,  Node: Network Socket Address,  Next: Network Sockets and Communication,  Prev: Network Databases,  Up: Networking

6.2.11.3 Network Socket Address
...............................

A “socket address” object identifies a socket endpoint for
communication.  In the case of ‘AF_INET’ for instance, the socket
address object comprises the host address (or interface on the host) and
a port number which specifies a particular open socket in a running
client or server process.  A socket address object can be created with,

 -- Scheme Procedure: make-socket-address AF_INET ipv4addr port
 -- Scheme Procedure: make-socket-address AF_INET6 ipv6addr port
          [flowinfo [scopeid]]
 -- Scheme Procedure: make-socket-address AF_UNIX path
 -- C Function: scm_make_socket_address family address arglist
     Return a new socket address object.  The first argument is the
     address family, one of the ‘AF’ constants, then the arguments vary
     according to the family.

     For ‘AF_INET’ the arguments are an IPv4 network address number
     (*note Network Address Conversion::), and a port number.

     For ‘AF_INET6’ the arguments are an IPv6 network address number and
     a port number.  Optional FLOWINFO and SCOPEID arguments may be
     given (both integers, default 0).

     For ‘AF_UNIX’ the argument is a filename (a string).

     The C function ‘scm_make_socket_address’ takes the FAMILY and
     ADDRESS arguments directly, then ARGLIST is a list of further
     arguments, being the port for IPv4, port and optional flowinfo and
     scopeid for IPv6, or the empty list ‘SCM_EOL’ for Unix domain.

The following functions access the fields of a socket address object,

 -- Scheme Procedure: sockaddr:fam sa
     Return the address family from socket address object SA.  This is
     one of the ‘AF’ constants (eg.  ‘AF_INET’).

 -- Scheme Procedure: sockaddr:path sa
     For an ‘AF_UNIX’ socket address object SA, return the filename.

 -- Scheme Procedure: sockaddr:addr sa
     For an ‘AF_INET’ or ‘AF_INET6’ socket address object SA, return the
     network address number.

 -- Scheme Procedure: sockaddr:port sa
     For an ‘AF_INET’ or ‘AF_INET6’ socket address object SA, return the
     port number.

 -- Scheme Procedure: sockaddr:flowinfo sa
     For an ‘AF_INET6’ socket address object SA, return the flowinfo
     value.

 -- Scheme Procedure: sockaddr:scopeid sa
     For an ‘AF_INET6’ socket address object SA, return the scope ID
     value.

   The functions below convert to and from the C ‘struct sockaddr’
(*note (libc)Address Formats::).  That structure is a generic type, an
application can cast to or from ‘struct sockaddr_in’, ‘struct
sockaddr_in6’ or ‘struct sockaddr_un’ according to the address family.

   In a ‘struct sockaddr’ taken or returned, the byte ordering in the
fields follows the C conventions (*note Byte Order Conversion:
(libc)Byte Order.).  This means network byte order for ‘AF_INET’ host
address (‘sin_addr.s_addr’) and port number (‘sin_port’), and ‘AF_INET6’
port number (‘sin6_port’).  But at the Scheme level these values are
taken or returned in host byte order, so the port is an ordinary
integer, and the host address likewise is an ordinary integer (as
described in *note Network Address Conversion::).

 -- C Function: struct sockaddr * scm_c_make_socket_address (SCM family,
          SCM address, SCM args, size_t *outsize)
     Return a newly-‘malloc’ed ‘struct sockaddr’ created from arguments
     like those taken by ‘scm_make_socket_address’ above.

     The size (in bytes) of the ‘struct sockaddr’ return is stored into
     ‘*OUTSIZE’.  An application must call ‘free’ to release the
     returned structure when no longer required.

 -- C Function: SCM scm_from_sockaddr (const struct sockaddr *address,
          unsigned address_size)
     Return a Scheme socket address object from the C ADDRESS structure.
     ADDRESS_SIZE is the size in bytes of ADDRESS.

 -- C Function: struct sockaddr * scm_to_sockaddr (SCM address, size_t
          *address_size)
     Return a newly-‘malloc’ed ‘struct sockaddr’ from a Scheme level
     socket address object.

     The size (in bytes) of the ‘struct sockaddr’ return is stored into
     ‘*OUTSIZE’.  An application must call ‘free’ to release the
     returned structure when no longer required.


File: guile.info,  Node: Network Sockets and Communication,  Next: Internet Socket Examples,  Prev: Network Socket Address,  Up: Networking

6.2.11.4 Network Sockets and Communication
..........................................

Socket ports can be created using ‘socket’ and ‘socketpair’.  The ports
are initially unbuffered, to make reading and writing to the same port
more reliable.  A buffer can be added to the port using ‘setvbuf’; see
*note Ports and File Descriptors::.

   Most systems have limits on how many files and sockets can be open,
so it's strongly recommended that socket ports be closed explicitly when
no longer required (*note Ports::).

   Some of the underlying C functions take values in network byte order,
but the convention in Guile is that at the Scheme level everything is
ordinary host byte order and conversions are made automatically where
necessary.

 -- Scheme Procedure: socket family style proto
 -- C Function: scm_socket (family, style, proto)
     Return a new socket port of the type specified by FAMILY, STYLE and
     PROTO.  All three parameters are integers.  The possible values for
     FAMILY are as follows, where supported by the system,

      -- Variable: PF_UNIX
      -- Variable: PF_INET
      -- Variable: PF_INET6

     The possible values for STYLE are as follows, again where supported
     by the system,

      -- Variable: SOCK_STREAM
      -- Variable: SOCK_DGRAM
      -- Variable: SOCK_RAW
      -- Variable: SOCK_RDM
      -- Variable: SOCK_SEQPACKET

     PROTO can be obtained from a protocol name using ‘getprotobyname’
     (*note Network Databases::).  A value of zero means the default
     protocol, which is usually right.

     A socket cannot by used for communication until it has been
     connected somewhere, usually with either ‘connect’ or ‘accept’
     below.

 -- Scheme Procedure: socketpair family style proto
 -- C Function: scm_socketpair (family, style, proto)
     Return a pair, the ‘car’ and ‘cdr’ of which are two unnamed socket
     ports connected to each other.  The connection is full-duplex, so
     data can be transferred in either direction between the two.

     FAMILY, STYLE and PROTO are as per ‘socket’ above.  But many
     systems only support socket pairs in the ‘PF_UNIX’ family.  Zero is
     likely to be the only meaningful value for PROTO.

 -- Scheme Procedure: getsockopt sock level optname
 -- Scheme Procedure: setsockopt sock level optname value
 -- C Function: scm_getsockopt (sock, level, optname)
 -- C Function: scm_setsockopt (sock, level, optname, value)
     Get or set an option on socket port SOCK.  ‘getsockopt’ returns the
     current value.  ‘setsockopt’ sets a value and the return is
     unspecified.

     LEVEL is an integer specifying a protocol layer, either
     ‘SOL_SOCKET’ for socket level options, or a protocol number from
     the ‘IPPROTO’ constants or ‘getprotoent’ (*note Network
     Databases::).

      -- Variable: SOL_SOCKET
      -- Variable: IPPROTO_IP
      -- Variable: IPPROTO_TCP
      -- Variable: IPPROTO_UDP

     OPTNAME is an integer specifying an option within the protocol
     layer.

     For ‘SOL_SOCKET’ level the following OPTNAMEs are defined (when
     provided by the system).  For their meaning see *note
     (libc)Socket-Level Options::, or ‘man 7 socket’.

      -- Variable: SO_DEBUG
      -- Variable: SO_REUSEADDR
      -- Variable: SO_STYLE
      -- Variable: SO_TYPE
      -- Variable: SO_ERROR
      -- Variable: SO_DONTROUTE
      -- Variable: SO_BROADCAST
      -- Variable: SO_SNDBUF
      -- Variable: SO_RCVBUF
      -- Variable: SO_KEEPALIVE
      -- Variable: SO_OOBINLINE
      -- Variable: SO_NO_CHECK
      -- Variable: SO_PRIORITY
          The VALUE taken or returned is an integer.

      -- Variable: SO_LINGER
          The VALUE taken or returned is a pair of integers ‘(ENABLE .
          TIMEOUT)’.  On old systems without timeout support (ie.
          without ‘struct linger’), only ENABLE has an effect but the
          value in Guile is always a pair.

     For IP level (‘IPPROTO_IP’) the following OPTNAMEs are defined
     (when provided by the system).  See ‘man ip’ for what they mean.

      -- Variable: IP_ADD_MEMBERSHIP
      -- Variable: IP_DROP_MEMBERSHIP
          These can be used only with ‘setsockopt’, not ‘getsockopt’.
          VALUE is a pair ‘(MULTIADDR . INTERFACEADDR)’ of integer IPv4
          addresses (*note Network Address Conversion::).  MULTIADDR is
          a multicast address to be added to or dropped from the
          interface INTERFACEADDR.  INTERFACEADDR can be ‘INADDR_ANY’ to
          have the system select the interface.  INTERFACEADDR can also
          be an interface index number, on systems supporting that.

 -- Scheme Procedure: shutdown sock how
 -- C Function: scm_shutdown (sock, how)
     Sockets can be closed simply by using ‘close-port’.  The ‘shutdown’
     procedure allows reception or transmission on a connection to be
     shut down individually, according to the parameter HOW:

     0
          Stop receiving data for this socket.  If further data arrives,
          reject it.
     1
          Stop trying to transmit data from this socket.  Discard any
          data waiting to be sent.  Stop looking for acknowledgement of
          data already sent; don't retransmit it if it is lost.
     2
          Stop both reception and transmission.

     The return value is unspecified.

 -- Scheme Procedure: connect sock sockaddr
 -- Scheme Procedure: connect sock AF_INET ipv4addr port
 -- Scheme Procedure: connect sock AF_INET6 ipv6addr port [flowinfo
          [scopeid]]
 -- Scheme Procedure: connect sock AF_UNIX path
 -- C Function: scm_connect (sock, fam, address, args)
     Initiate a connection on socket port SOCK to a given address.  The
     destination is either a socket address object, or arguments the
     same as ‘make-socket-address’ would take to make such an object
     (*note Network Socket Address::).  The return value is unspecified.

          (connect sock AF_INET INADDR_LOOPBACK 23)
          (connect sock (make-socket-address AF_INET INADDR_LOOPBACK 23))

 -- Scheme Procedure: bind sock sockaddr
 -- Scheme Procedure: bind sock AF_INET ipv4addr port
 -- Scheme Procedure: bind sock AF_INET6 ipv6addr port [flowinfo
          [scopeid]]
 -- Scheme Procedure: bind sock AF_UNIX path
 -- C Function: scm_bind (sock, fam, address, args)
     Bind socket port SOCK to the given address.  The address is either
     a socket address object, or arguments the same as
     ‘make-socket-address’ would take to make such an object (*note
     Network Socket Address::).  The return value is unspecified.

     Generally a socket is only explicitly bound to a particular address
     when making a server, ie.  to listen on a particular port.  For an
     outgoing connection the system will assign a local address
     automatically, if not already bound.

          (bind sock AF_INET INADDR_ANY 12345)
          (bind sock (make-socket-address AF_INET INADDR_ANY 12345))

 -- Scheme Procedure: listen sock backlog
 -- C Function: scm_listen (sock, backlog)
     Enable SOCK to accept connection requests.  BACKLOG is an integer
     specifying the maximum length of the queue for pending connections.
     If the queue fills, new clients will fail to connect until the
     server calls ‘accept’ to accept a connection from the queue.

     The return value is unspecified.

 -- Scheme Procedure: accept sock
 -- C Function: scm_accept (sock)
     Accept a connection from socket port SOCK which has been enabled
     for listening with ‘listen’ above.  If there are no incoming
     connections in the queue, wait until one is available (unless
     ‘O_NONBLOCK’ has been set on the socket, *note ‘fcntl’: Ports and
     File Descriptors.).

     The return value is a pair.  The ‘car’ is a new socket port,
     connected and ready to communicate.  The ‘cdr’ is a socket address
     object (*note Network Socket Address::) which is where the remote
     connection is from (like ‘getpeername’ below).

     All communication takes place using the new socket returned.  The
     given SOCK remains bound and listening, and ‘accept’ may be called
     on it again to get another incoming connection when desired.

 -- Scheme Procedure: getsockname sock
 -- C Function: scm_getsockname (sock)
     Return a socket address object which is the where SOCK is bound
     locally.  SOCK may have obtained its local address from ‘bind’
     (above), or if a ‘connect’ is done with an otherwise unbound socket
     (which is usual) then the system will have assigned an address.

     Note that on many systems the address of a socket in the ‘AF_UNIX’
     namespace cannot be read.

 -- Scheme Procedure: getpeername sock
 -- C Function: scm_getpeername (sock)
     Return a socket address object which is where SOCK is connected to,
     ie.  the remote endpoint.

     Note that on many systems the address of a socket in the ‘AF_UNIX’
     namespace cannot be read.

 -- Scheme Procedure: recv! sock buf [flags]
 -- C Function: scm_recv (sock, buf, flags)
     Receive data from a socket port.  SOCK must already be bound to the
     address from which data is to be received.  BUF is a string into
     which the data will be written.  The size of BUF limits the amount
     of data which can be received: in the case of packet protocols, if
     a packet larger than this limit is encountered then some data will
     be irrevocably lost.

     The optional FLAGS argument is a value or bitwise OR of ‘MSG_OOB’,
     ‘MSG_PEEK’, ‘MSG_DONTROUTE’ etc.

     The value returned is the number of bytes read from the socket.

     Note that the data is read directly from the socket file
     descriptor: any unread buffered port data is ignored.

 -- Scheme Procedure: send sock message [flags]
 -- C Function: scm_send (sock, message, flags)
     Transmit the string MESSAGE on a socket port SOCK.  SOCK must
     already be bound to a destination address.  The value returned is
     the number of bytes transmitted--it's possible for this to be less
     than the length of MESSAGE if the socket is set to be non-blocking.
     The optional FLAGS argument is a value or bitwise OR of ‘MSG_OOB’,
     ‘MSG_PEEK’, ‘MSG_DONTROUTE’ etc.

     Note that the data is written directly to the socket file
     descriptor: any unflushed buffered port data is ignored.

 -- Scheme Procedure: recvfrom! sock str [flags [start [end]]]
 -- C Function: scm_recvfrom (sock, str, flags, start, end)
     Receive data from socket port SOCK, returning the originating
     address as well as the data.  This function is usually for datagram
     sockets, but can be used on stream-oriented sockets too.

     The data received is stored in the given STR, the whole string or
     just the region between the optional START and END positions.  The
     size of STR limits the amount of data which can be received.  For
     datagram protocols if a packet larger than this is received then
     excess bytes are irrevocably lost.

     The return value is a pair.  The ‘car’ is the number of bytes read.
     The ‘cdr’ is a socket address object (*note Network Socket
     Address::) which is where the data came from, or ‘#f’ if the origin
     is unknown.

     The optional FLAGS argument is a or bitwise-OR (‘logior’) of
     ‘MSG_OOB’, ‘MSG_PEEK’, ‘MSG_DONTROUTE’ etc.

     Data is read directly from the socket file descriptor, any buffered
     port data is ignored.

     On a GNU/Linux system ‘recvfrom!’ is not multi-threading, all
     threads stop while a ‘recvfrom!’ call is in progress.  An
     application may need to use ‘select’, ‘O_NONBLOCK’ or
     ‘MSG_DONTWAIT’ to avoid this.

 -- Scheme Procedure: sendto sock message sockaddr [flags]
 -- Scheme Procedure: sendto sock message AF_INET ipv4addr port [flags]
 -- Scheme Procedure: sendto sock message AF_INET6 ipv6addr port
          [flowinfo [scopeid [flags]]]
 -- Scheme Procedure: sendto sock message AF_UNIX path [flags]
 -- C Function: scm_sendto (sock, message, fam, address, args_and_flags)
     Transmit the string MESSAGE as a datagram on socket port SOCK.  The
     destination is specified either as a socket address object, or as
     arguments the same as would be taken by ‘make-socket-address’ to
     create such an object (*note Network Socket Address::).

     The destination address may be followed by an optional FLAGS
     argument which is a ‘logior’ (*note Bitwise Operations::) of
     ‘MSG_OOB’, ‘MSG_PEEK’, ‘MSG_DONTROUTE’ etc.

     The value returned is the number of bytes transmitted - it's
     possible for this to be less than the length of MESSAGE if the
     socket is set to be non-blocking.  Note that the data is written
     directly to the socket file descriptor: any unflushed buffered port
     data is ignored.

   The following functions can be used to convert short and long
integers between "host" and "network" order.  Although the procedures
above do this automatically for addresses, the conversion will still
need to be done when sending or receiving encoded integer data from the
network.

 -- Scheme Procedure: htons value
 -- C Function: scm_htons (value)
     Convert a 16 bit quantity from host to network byte ordering.
     VALUE is packed into 2 bytes, which are then converted and returned
     as a new integer.

 -- Scheme Procedure: ntohs value
 -- C Function: scm_ntohs (value)
     Convert a 16 bit quantity from network to host byte ordering.
     VALUE is packed into 2 bytes, which are then converted and returned
     as a new integer.

 -- Scheme Procedure: htonl value
 -- C Function: scm_htonl (value)
     Convert a 32 bit quantity from host to network byte ordering.
     VALUE is packed into 4 bytes, which are then converted and returned
     as a new integer.

 -- Scheme Procedure: ntohl value
 -- C Function: scm_ntohl (value)
     Convert a 32 bit quantity from network to host byte ordering.
     VALUE is packed into 4 bytes, which are then converted and returned
     as a new integer.

   These procedures are inconvenient to use at present, but consider:

     (define write-network-long
       (lambda (value port)
         (let ((v (make-uniform-vector 1 1 0)))
           (uniform-vector-set! v 0 (htonl value))
           (uniform-vector-write v port))))

     (define read-network-long
       (lambda (port)
         (let ((v (make-uniform-vector 1 1 0)))
           (uniform-vector-read! v port)
           (ntohl (uniform-vector-ref v 0)))))


File: guile.info,  Node: Internet Socket Examples,  Prev: Network Sockets and Communication,  Up: Networking

6.2.11.5 Network Socket Examples
................................

The following give examples of how to use network sockets.

Internet Socket Client Example
..............................

The following example demonstrates an Internet socket client.  It
connects to the HTTP daemon running on the local machine and returns the
contents of the root index URL.

     (let ((s (socket PF_INET SOCK_STREAM 0)))
       (connect s AF_INET (inet-aton "127.0.0.1") 80)
       (display "GET / HTTP/1.0\r\n\r\n" s)

       (do ((line (read-line s) (read-line s)))
           ((eof-object? line))
         (display line)
         (newline)))

Internet Socket Server Example
..............................

The following example shows a simple Internet server which listens on
port 2904 for incoming connections and sends a greeting back to the
client.

     (let ((s (socket PF_INET SOCK_STREAM 0)))
       (setsockopt s SOL_SOCKET SO_REUSEADDR 1)
       ;; Specific address?
       ;; (bind s AF_INET (inet-aton "127.0.0.1") 2904)
       (bind s AF_INET INADDR_ANY 2904)
       (listen s 5)

       (simple-format #t "Listening for clients in pid: ~S" (getpid))
       (newline)

       (while #t
         (let* ((client-connection (accept s))
                (client-details (cdr client-connection))
                (client (car client-connection)))
           (simple-format #t "Got new client connection: ~S"
                          client-details)
           (newline)
           (simple-format #t "Client address: ~S"
                          (gethostbyaddr
                           (sockaddr:addr client-details)))
           (newline)
           ;; Send back the greeting to the client port
           (display "Hello client\r\n" client)
           (close client))))


File: guile.info,  Node: System Identification,  Next: Locales,  Prev: Networking,  Up: POSIX

6.2.12 System Identification
----------------------------

This section lists the various procedures Guile provides for accessing
information about the system it runs on.

 -- Scheme Procedure: uname
 -- C Function: scm_uname ()
     Return an object with some information about the computer system
     the program is running on.

     The following procedures accept an object as returned by ‘uname’
     and return a selected component (all of which are strings).

      -- Scheme Procedure: utsname:sysname un
          The name of the operating system.
      -- Scheme Procedure: utsname:nodename un
          The network name of the computer.
      -- Scheme Procedure: utsname:release un
          The current release level of the operating system
          implementation.
      -- Scheme Procedure: utsname:version un
          The current version level within the release of the operating
          system.
      -- Scheme Procedure: utsname:machine un
          A description of the hardware.

 -- Scheme Procedure: gethostname
 -- C Function: scm_gethostname ()
     Return the host name of the current processor.

 -- Scheme Procedure: sethostname name
 -- C Function: scm_sethostname (name)
     Set the host name of the current processor to NAME.  May only be
     used by the superuser.  The return value is not specified.


File: guile.info,  Node: Locales,  Next: Encryption,  Prev: System Identification,  Up: POSIX

6.2.13 Locales
--------------

 -- Scheme Procedure: setlocale category [locale]
 -- C Function: scm_setlocale (category, locale)
     Get or set the current locale, used for various
     internationalizations.  Locales are strings, such as ‘sv_SE’.

     If LOCALE is given then the locale for the given CATEGORY is set
     and the new value returned.  If LOCALE is not given then the
     current value is returned.  CATEGORY should be one of the following
     values

      -- Variable: LC_ALL
      -- Variable: LC_COLLATE
      -- Variable: LC_CTYPE
      -- Variable: LC_MESSAGES
      -- Variable: LC_MONETARY
      -- Variable: LC_NUMERIC
      -- Variable: LC_TIME

     A common usage is ‘(setlocale LC_ALL "")’, which initializes all
     categories based on standard environment variables (‘LANG’ etc).
     For full details on categories and locale names *note Locales and
     Internationalization: (libc)Locales.


File: guile.info,  Node: Encryption,  Prev: Locales,  Up: POSIX

6.2.14 Encryption
-----------------

Please note that the procedures in this section are not suited for
strong encryption, they are only interfaces to the well-known and common
system library functions of the same name.  They are just as good (or
bad) as the underlying functions, so you should refer to your system
documentation before using them (*note Encrypting Passwords:
(libc)crypt.).

 -- Scheme Procedure: crypt key salt
 -- C Function: scm_crypt (key, salt)
     Encrypt KEY, with the addition of SALT (both strings), using the
     ‘crypt’ C library call.

   Although ‘getpass’ is not an encryption procedure per se, it appears
here because it is often used in combination with ‘crypt’:

 -- Scheme Procedure: getpass prompt
 -- C Function: scm_getpass (prompt)
     Display PROMPT to the standard error output and read a password
     from ‘/dev/tty’.  If this file is not accessible, it reads from
     standard input.  The password may be up to 127 characters in
     length.  Additional characters and the terminating newline
     character are discarded.  While reading the password, echoing and
     the generation of signals by special characters is disabled.


File: guile.info,  Node: getopt-long,  Next: SRFI Support,  Prev: POSIX,  Up: Guile Modules

6.3 The (ice-9 getopt-long) Module
==================================

The ‘(ice-9 getopt-long)’ module exports two procedures: ‘getopt-long’
and ‘option-ref’.

   • ‘getopt-long’ takes a list of strings -- the command line arguments
     -- and an “option specification”.  It parses the command line
     arguments according to the option specification and returns a data
     structure that encapsulates the results of the parsing.

   • ‘option-ref’ then takes the parsed data structure and a specific
     option's name, and returns information about that option in
     particular.

   To make these procedures available to your Guile script, include the
expression ‘(use-modules (ice-9 getopt-long))’ somewhere near the top,
before the first usage of ‘getopt-long’ or ‘option-ref’.

* Menu:

* getopt-long Example::         A short getopt-long example.
* Option Specification::        How to write an option specification.
* Command Line Format::         The expected command line format.
* getopt-long Reference::       Full documentation for ‘getopt-long’.
* option-ref Reference::        Full documentation for ‘option-ref’.


File: guile.info,  Node: getopt-long Example,  Next: Option Specification,  Up: getopt-long

6.3.1 A Short getopt-long Example
---------------------------------

This section illustrates how ‘getopt-long’ is used by presenting and
dissecting a simple example.  The first thing that we need is an “option
specification” that tells ‘getopt-long’ how to parse the command line.
This specification is an association list with the long option name as
the key.  Here is how such a specification might look:

     (define option-spec
       '((version (single-char #\v) (value #f))
         (help    (single-char #\h) (value #f))))

   This alist tells ‘getopt-long’ that it should accept two long
options, called _version_ and _help_, and that these options can also be
selected by the single-letter abbreviations _v_ and _h_, respectively.
The ‘(value #f)’ clauses indicate that neither of the options accepts a
value.

   With this specification we can use ‘getopt-long’ to parse a given
command line:

     (define options (getopt-long (command-line) option-spec))

   After this call, ‘options’ contains the parsed command line and is
ready to be examined by ‘option-ref’.  ‘option-ref’ is called like this:

     (option-ref options 'help #f)

It expects the parsed command line, a symbol indicating the option to
examine, and a default value.  The default value is returned if the
option was not present in the command line, or if the option was present
but without a value; otherwise the value from the command line is
returned.  Usually ‘option-ref’ is called once for each possible option
that a script supports.

   The following example shows a main program which puts all this
together to parse its command line and figure out what the user wanted.

     (define (main args)
       (let* ((option-spec '((version (single-char #\v) (value #f))
                             (help    (single-char #\h) (value #f))))
              (options (getopt-long args option-spec))
              (help-wanted (option-ref options 'help #f))
              (version-wanted (option-ref options 'version #f)))
         (if (or version-wanted help-wanted)
             (begin
               (if version-wanted
                   (display "getopt-long-example version 0.3\n"))
               (if help-wanted
                   (display "\
     getopt-long-example [options]
       -v, --version    Display version
       -h, --help       Display this help
     ")))
             (begin
               (display "Hello, World!") (newline)))))


File: guile.info,  Node: Option Specification,  Next: Command Line Format,  Prev: getopt-long Example,  Up: getopt-long

6.3.2 How to Write an Option Specification
------------------------------------------

An option specification is an association list (*note Association
Lists::) with one list element for each supported option.  The key of
each list element is a symbol that names the option, while the value is
a list of option properties:

     OPTION-SPEC ::=  '( (OPT-NAME1 (PROP-NAME PROP-VALUE) ...)
                         (OPT-NAME2 (PROP-NAME PROP-VALUE) ...)
                         (OPT-NAME3 (PROP-NAME PROP-VALUE) ...)
                         ...
                       )

   Each OPT-NAME specifies the long option name for that option.  For
example, a list element with OPT-NAME ‘background’ specifies an option
that can be specified on the command line using the long option
‘--background’.  Further information about the option -- whether it
takes a value, whether it is required to be present in the command line,
and so on -- is specified by the option properties.

   In the example of the preceding section, we already saw that a long
option name can have a equivalent “short option” character.  The
equivalent short option character can be set for an option by specifying
a ‘single-char’ property in that option's property list.  For example, a
list element like ‘'(output (single-char #\o) ...)’ specifies an option
with long name ‘--output’ that can also be specified by the equivalent
short name ‘-o’.

   The ‘value’ property specifies whether an option requires or accepts
a value.  If the ‘value’ property is set to ‘#t’, the option requires a
value: ‘getopt-long’ will signal an error if the option name is present
without a corresponding value.  If set to ‘#f’, the option does not take
a value; in this case, a non-option word that follows the option name in
the command line will be treated as a non-option argument.  If set to
the symbol ‘optional’, the option accepts a value but does not require
one: a non-option word that follows the option name in the command line
will be interpreted as that option's value.  If the option name for an
option with ‘'(value optional)’ is immediately followed in the command
line by _another_ option name, the value for the first option is
implicitly ‘#t’.

   The ‘required?’ property indicates whether an option is required to
be present in the command line.  If the ‘required?’ property is set to
‘#t’, ‘getopt-long’ will signal an error if the option is not specified.

   Finally, the ‘predicate’ property can be used to constrain the
possible values of an option.  If used, the ‘predicate’ property should
be set to a procedure that takes one argument -- the proposed option
value as a string -- and returns either ‘#t’ or ‘#f’ according as the
proposed value is or is not acceptable.  If the predicate procedure
returns ‘#f’, ‘getopt-long’ will signal an error.

   By default, options do not have single-character equivalents, are not
required, and do not take values.  Where the list element for an option
includes a ‘value’ property but no ‘predicate’ property, the option
values are unconstrained.


File: guile.info,  Node: Command Line Format,  Next: getopt-long Reference,  Prev: Option Specification,  Up: getopt-long

6.3.3 Expected Command Line Format
----------------------------------

In order for ‘getopt-long’ to correctly parse a command line, that
command line must conform to a standard set of rules for how command
line options are specified.  This section explains what those rules are.

   ‘getopt-long’ splits a given command line into several pieces.  All
elements of the argument list are classified to be either options or
normal arguments.  Options consist of two dashes and an option name
(so-called “long” options), or of one dash followed by a single letter
(“short” options).

   Options can behave as switches, when they are given without a value,
or they can be used to pass a value to the program.  The value for an
option may be specified using an equals sign, or else is simply the next
word in the command line, so the following two invocations are
equivalent:

     $ ./foo.scm --output=bar.txt
     $ ./foo.scm --output bar.txt

   Short options can be used instead of their long equivalents and can
be grouped together after a single dash.  For example, the following
commands are equivalent.

     $ ./foo.scm --version --help
     $ ./foo.scm -v --help
     $ ./foo.scm -vh

   If an option requires a value, it can only be grouped together with
other short options if it is the last option in the group; the value is
the next argument.  So, for example, with the following option
specification --

     ((apples    (single-char #\a))
      (blimps    (single-char #\b) (value #t))
      (catalexis (single-char #\c) (value #t)))

-- the following command lines would all be acceptable:

     $ ./foo.scm -a -b bang -c couth
     $ ./foo.scm -ab bang -c couth
     $ ./foo.scm -ac couth -b bang

   But the next command line is an error, because ‘-b’ is not the last
option in its combination, and because a group of short options cannot
include two options that both require values:

     $ ./foo.scm -abc couth bang

   If an option's value is optional, ‘getopt-long’ decides whether the
option has a value by looking at what follows it in the argument list.
If the next element is a string, and it does not appear to be an option
itself, then that string is the option's value.

   If the option ‘--’ appears in the argument list, argument parsing
stops there and subsequent arguments are returned as ordinary arguments,
even if they resemble options.  So, with the command line

     $ ./foo.scm --apples "Granny Smith" -- --blimp Goodyear

‘getopt-long’ will recognize the ‘--apples’ option as having the value
"Granny Smith", but will not treat ‘--blimp’ as an option.  The strings
‘--blimp’ and ‘Goodyear’ will be returned as ordinary argument strings.


File: guile.info,  Node: getopt-long Reference,  Next: option-ref Reference,  Prev: Command Line Format,  Up: getopt-long

6.3.4 Reference Documentation for ‘getopt-long’
-----------------------------------------------

 -- Scheme Procedure: getopt-long args grammar
     Parse the command line given in ARGS (which must be a list of
     strings) according to the option specification GRAMMAR.

     The GRAMMAR argument is expected to be a list of this form:

     ‘((OPTION (PROPERTY VALUE) ...) ...)’

     where each OPTION is a symbol denoting the long option, but without
     the two leading dashes (e.g.  ‘version’ if the option is called
     ‘--version’).

     For each option, there may be list of arbitrarily many
     property/value pairs.  The order of the pairs is not important, but
     every property may only appear once in the property list.  The
     following table lists the possible properties:

     ‘(single-char CHAR)’
          Accept ‘-CHAR’ as a single-character equivalent to ‘--OPTION’.
          This is how to specify traditional Unix-style flags.
     ‘(required? BOOL)’
          If BOOL is true, the option is required.  ‘getopt-long’ will
          raise an error if it is not found in ARGS.
     ‘(value BOOL)’
          If BOOL is ‘#t’, the option accepts a value; if it is ‘#f’, it
          does not; and if it is the symbol ‘optional’, the option may
          appear in ARGS with or without a value.
     ‘(predicate FUNC)’
          If the option accepts a value (i.e.  you specified ‘(value
          #t)’ for this option), then ‘getopt-long’ will apply FUNC to
          the value, and throw an exception if it returns ‘#f’.  FUNC
          should be a procedure which accepts a string and returns a
          boolean value; you may need to use quasiquotes to get it into
          GRAMMAR.

   ‘getopt-long’'s ARGS parameter is expected to be a list of strings
like the one returned by ‘command-line’, with the first element being
the name of the command.  Therefore ‘getopt-long’ ignores the first
element in ARGS and starts argument interpretation with the second
element.

   ‘getopt-long’ signals an error if any of the following conditions
hold.

   • The option grammar has an invalid syntax.

   • One of the options in the argument list was not specified by the
     grammar.

   • A required option is omitted.

   • An option which requires an argument did not get one.

   • An option that doesn't accept an argument does get one (this can
     only happen using the long option ‘--opt=VALUE’ syntax).

   • An option predicate fails.


File: guile.info,  Node: option-ref Reference,  Prev: getopt-long Reference,  Up: getopt-long

6.3.5 Reference Documentation for ‘option-ref’
----------------------------------------------

 -- Scheme Procedure: option-ref options key default
     Search OPTIONS for a command line option named KEY and return its
     value, if found.  If the option has no value, but was given, return
     ‘#t’.  If the option was not given, return DEFAULT.  OPTIONS must
     be the result of a call to ‘getopt-long’.

   ‘option-ref’ always succeeds, either by returning the requested
option value from the command line, or the default value.

   The special key ‘'()’ can be used to get a list of all non-option
arguments.


File: guile.info,  Node: SRFI Support,  Next: Readline Support,  Prev: getopt-long,  Up: Guile Modules

6.4 SRFI Support Modules
========================

SRFI is an acronym for Scheme Request For Implementation.  The SRFI
documents define a lot of syntactic and procedure extensions to standard
Scheme as defined in R5RS.

   Guile has support for a number of SRFIs.  This chapter gives an
overview over the available SRFIs and some usage hints.  For complete
documentation, design rationales and further examples, we advise you to
get the relevant SRFI documents from the SRFI home page
<http://srfi.schemers.org>.

* Menu:

* About SRFI Usage::            What to know about Guile's SRFI support.
* SRFI-0::                      cond-expand
* SRFI-1::                      List library.
* SRFI-2::                      and-let*.
* SRFI-4::                      Homogeneous numeric vector datatypes.
* SRFI-6::                      Basic String Ports.
* SRFI-8::                      receive.
* SRFI-9::                      define-record-type.
* SRFI-10::                     Hash-Comma Reader Extension.
* SRFI-11::                     let-values and let*-values.
* SRFI-13::                     String library.
* SRFI-14::                     Character-set library.
* SRFI-16::                     case-lambda
* SRFI-17::                     Generalized set!
* SRFI-19::                     Time/Date library.
* SRFI-26::                     Specializing parameters
* SRFI-31::                     A special form 'rec' for recursive evaluation
* SRFI-34::                     Exception handling.
* SRFI-35::                     Conditions.
* SRFI-37::                     args-fold program argument processor
* SRFI-39::                     Parameter objects
* SRFI-55::                     Requiring Features.
* SRFI-60::                     Integers as bits.
* SRFI-61::                     A more general 'cond' clause
* SRFI-69::                     Basic hash tables.
* SRFI-88::                     Keyword objects.


File: guile.info,  Node: About SRFI Usage,  Next: SRFI-0,  Up: SRFI Support

6.4.1 About SRFI Usage
----------------------

SRFI support in Guile is currently implemented partly in the core
library, and partly as add-on modules.  That means that some SRFIs are
automatically available when the interpreter is started, whereas the
other SRFIs require you to use the appropriate support module
explicitly.

   There are several reasons for this inconsistency.  First, the feature
checking syntactic form ‘cond-expand’ (*note SRFI-0::) must be available
immediately, because it must be there when the user wants to check for
the Scheme implementation, that is, before she can know that it is safe
to use ‘use-modules’ to load SRFI support modules.  The second reason is
that some features defined in SRFIs had been implemented in Guile before
the developers started to add SRFI implementations as modules (for
example SRFI-6 (*note SRFI-6::)).  In the future, it is possible that
SRFIs in the core library might be factored out into separate modules,
requiring explicit module loading when they are needed.  So you should
be prepared to have to use ‘use-modules’ someday in the future to access
SRFI-6 bindings.  If you want, you can do that already.  We have
included the module ‘(srfi srfi-6)’ in the distribution, which currently
does nothing, but ensures that you can write future-safe code.

   Generally, support for a specific SRFI is made available by using
modules named ‘(srfi srfi-NUMBER)’, where NUMBER is the number of the
SRFI needed.  Another possibility is to use the command line option
‘--use-srfi’, which will load the necessary modules automatically (*note
Invoking Guile::).


File: guile.info,  Node: SRFI-0,  Next: SRFI-1,  Prev: About SRFI Usage,  Up: SRFI Support

6.4.2 SRFI-0 - cond-expand
--------------------------

This SRFI lets a portable Scheme program test for the presence of
certain features, and adapt itself by using different blocks of code, or
fail if the necessary features are not available.  There's no module to
load, this is in the Guile core.

   A program designed only for Guile will generally not need this
mechanism, such a program can of course directly use the various
documented parts of Guile.

 -- syntax: cond-expand (feature body...) ...
     Expand to the BODY of the first clause whose FEATURE specification
     is satisfied.  It is an error if no FEATURE is satisfied.

     Features are symbols such as ‘srfi-1’, and a feature specification
     can use ‘and’, ‘or’ and ‘not’ forms to test combinations.  The last
     clause can be an ‘else’, to be used if no other passes.

     For example, define a private version of ‘alist-cons’ if SRFI-1 is
     not available.

          (cond-expand (srfi-1
                        )
                       (else
                        (define (alist-cons key val alist)
                          (cons (cons key val) alist))))

     Or demand a certain set of SRFIs (list operations, string ports,
     ‘receive’ and string operations), failing if they're not available.

          (cond-expand ((and srfi-1 srfi-6 srfi-8 srfi-13)
                        ))

The Guile core has the following features,

     guile
     r5rs
     srfi-0
     srfi-4
     srfi-6
     srfi-13
     srfi-14

   Other SRFI feature symbols are defined once their code has been
loaded with ‘use-modules’, since only then are their bindings available.

   The ‘--use-srfi’ command line option (*note Invoking Guile::) is a
good way to load SRFIs to satisfy ‘cond-expand’ when running a portable
program.

   Testing the ‘guile’ feature allows a program to adapt itself to the
Guile module system, but still run on other Scheme systems.  For example
the following demands SRFI-8 (‘receive’), but also knows how to load it
with the Guile mechanism.

     (cond-expand (srfi-8
                   )
                  (guile
                   (use-modules (srfi srfi-8))))

   It should be noted that ‘cond-expand’ is separate from the
‘*features*’ mechanism (*note Feature Tracking::), feature symbols in
one are unrelated to those in the other.


File: guile.info,  Node: SRFI-1,  Next: SRFI-2,  Prev: SRFI-0,  Up: SRFI Support

6.4.3 SRFI-1 - List library
---------------------------

The list library defined in SRFI-1 contains a lot of useful list
processing procedures for construction, examining, destructuring and
manipulating lists and pairs.

   Since SRFI-1 also defines some procedures which are already contained
in R5RS and thus are supported by the Guile core library, some list and
pair procedures which appear in the SRFI-1 document may not appear in
this section.  So when looking for a particular list/pair processing
procedure, you should also have a look at the sections *note Lists:: and
*note Pairs::.

* Menu:

* SRFI-1 Constructors::         Constructing new lists.
* SRFI-1 Predicates::           Testing list for specific properties.
* SRFI-1 Selectors::            Selecting elements from lists.
* SRFI-1 Length Append etc::    Length calculation and list appending.
* SRFI-1 Fold and Map::         Higher-order list processing.
* SRFI-1 Filtering and Partitioning::  Filter lists based on predicates.
* SRFI-1 Searching::            Search for elements.
* SRFI-1 Deleting::             Delete elements from lists.
* SRFI-1 Association Lists::    Handle association lists.
* SRFI-1 Set Operations::       Use lists for representing sets.


File: guile.info,  Node: SRFI-1 Constructors,  Next: SRFI-1 Predicates,  Up: SRFI-1

6.4.3.1 Constructors
....................

New lists can be constructed by calling one of the following procedures.

 -- Scheme Procedure: xcons d a
     Like ‘cons’, but with interchanged arguments.  Useful mostly when
     passed to higher-order procedures.

 -- Scheme Procedure: list-tabulate n init-proc
     Return an N-element list, where each list element is produced by
     applying the procedure INIT-PROC to the corresponding list index.
     The order in which INIT-PROC is applied to the indices is not
     specified.

 -- Scheme Procedure: list-copy lst
     Return a new list containing the elements of the list LST.

     This function differs from the core ‘list-copy’ (*note List
     Constructors::) in accepting improper lists too.  And if LST is not
     a pair at all then it's treated as the final tail of an improper
     list and simply returned.

 -- Scheme Procedure: circular-list elt1 elt2 ...
     Return a circular list containing the given arguments ELT1 ELT2
     ....

 -- Scheme Procedure: iota count [start step]
     Return a list containing COUNT numbers, starting from START and
     adding STEP each time.  The default START is 0, the default STEP is
     1.  For example,

          (iota 6)        ⇒ (0 1 2 3 4 5)
          (iota 4 2.5 -2) ⇒ (2.5 0.5 -1.5 -3.5)

     This function takes its name from the corresponding primitive in
     the APL language.


File: guile.info,  Node: SRFI-1 Predicates,  Next: SRFI-1 Selectors,  Prev: SRFI-1 Constructors,  Up: SRFI-1

6.4.3.2 Predicates
..................

The procedures in this section test specific properties of lists.

 -- Scheme Procedure: proper-list? obj
     Return ‘#t’ if OBJ is a proper list, or ‘#f’ otherwise.  This is
     the same as the core ‘list?’ (*note List Predicates::).

     A proper list is a list which ends with the empty list ‘()’ in the
     usual way.  The empty list ‘()’ itself is a proper list too.

          (proper-list? '(1 2 3))  ⇒ #t
          (proper-list? '())       ⇒ #t

 -- Scheme Procedure: circular-list? obj
     Return ‘#t’ if OBJ is a circular list, or ‘#f’ otherwise.

     A circular list is a list where at some point the ‘cdr’ refers back
     to a previous pair in the list (either the start or some later
     point), so that following the ‘cdr’s takes you around in a circle,
     with no end.

          (define x (list 1 2 3 4))
          (set-cdr! (last-pair x) (cddr x))
          x ⇒ (1 2 3 4 3 4 3 4 ...)
          (circular-list? x)  ⇒ #t

 -- Scheme Procedure: dotted-list? obj
     Return ‘#t’ if OBJ is a dotted list, or ‘#f’ otherwise.

     A dotted list is a list where the ‘cdr’ of the last pair is not the
     empty list ‘()’.  Any non-pair OBJ is also considered a dotted
     list, with length zero.

          (dotted-list? '(1 2 . 3))  ⇒ #t
          (dotted-list? 99)          ⇒ #t

   It will be noted that any Scheme object passes exactly one of the
above three tests ‘proper-list?’, ‘circular-list?’ and ‘dotted-list?’.
Non-lists are ‘dotted-list?’, finite lists are either ‘proper-list?’ or
‘dotted-list?’, and infinite lists are ‘circular-list?’.


 -- Scheme Procedure: null-list? lst
     Return ‘#t’ if LST is the empty list ‘()’, ‘#f’ otherwise.  If
     something else than a proper or circular list is passed as LST, an
     error is signalled.  This procedure is recommended for checking for
     the end of a list in contexts where dotted lists are not allowed.

 -- Scheme Procedure: not-pair? obj
     Return ‘#t’ is OBJ is not a pair, ‘#f’ otherwise.  This is
     shorthand notation ‘(not (pair? OBJ))’ and is supposed to be used
     for end-of-list checking in contexts where dotted lists are
     allowed.

 -- Scheme Procedure: list= elt= list1 ...
     Return ‘#t’ if all argument lists are equal, ‘#f’ otherwise.  List
     equality is determined by testing whether all lists have the same
     length and the corresponding elements are equal in the sense of the
     equality predicate ELT=.  If no or only one list is given, ‘#t’ is
     returned.


File: guile.info,  Node: SRFI-1 Selectors,  Next: SRFI-1 Length Append etc,  Prev: SRFI-1 Predicates,  Up: SRFI-1

6.4.3.3 Selectors
.................

 -- Scheme Procedure: first pair
 -- Scheme Procedure: second pair
 -- Scheme Procedure: third pair
 -- Scheme Procedure: fourth pair
 -- Scheme Procedure: fifth pair
 -- Scheme Procedure: sixth pair
 -- Scheme Procedure: seventh pair
 -- Scheme Procedure: eighth pair
 -- Scheme Procedure: ninth pair
 -- Scheme Procedure: tenth pair
     These are synonyms for ‘car’, ‘cadr’, ‘caddr’, ....

 -- Scheme Procedure: car+cdr pair
     Return two values, the CAR and the CDR of PAIR.

 -- Scheme Procedure: take lst i
 -- Scheme Procedure: take! lst i
     Return a list containing the first I elements of LST.

     ‘take!’ may modify the structure of the argument list LST in order
     to produce the result.

 -- Scheme Procedure: drop lst i
     Return a list containing all but the first I elements of LST.

 -- Scheme Procedure: take-right lst i
     Return the a list containing the I last elements of LST.  The
     return shares a common tail with LST.

 -- Scheme Procedure: drop-right lst i
 -- Scheme Procedure: drop-right! lst i
     Return the a list containing all but the I last elements of LST.

     ‘drop-right’ always returns a new list, even when I is zero.
     ‘drop-right!’ may modify the structure of the argument list LST in
     order to produce the result.

 -- Scheme Procedure: split-at lst i
 -- Scheme Procedure: split-at! lst i
     Return two values, a list containing the first I elements of the
     list LST and a list containing the remaining elements.

     ‘split-at!’ may modify the structure of the argument list LST in
     order to produce the result.

 -- Scheme Procedure: last lst
     Return the last element of the non-empty, finite list LST.


File: guile.info,  Node: SRFI-1 Length Append etc,  Next: SRFI-1 Fold and Map,  Prev: SRFI-1 Selectors,  Up: SRFI-1

6.4.3.4 Length, Append, Concatenate, etc.
.........................................

 -- Scheme Procedure: length+ lst
     Return the length of the argument list LST.  When LST is a circular
     list, ‘#f’ is returned.

 -- Scheme Procedure: concatenate list-of-lists
 -- Scheme Procedure: concatenate! list-of-lists
     Construct a list by appending all lists in LIST-OF-LISTS.

     ‘concatenate!’ may modify the structure of the given lists in order
     to produce the result.

     ‘concatenate’ is the same as ‘(apply append LIST-OF-LISTS)’.  It
     exists because some Scheme implementations have a limit on the
     number of arguments a function takes, which the ‘apply’ might
     exceed.  In Guile there is no such limit.

 -- Scheme Procedure: append-reverse rev-head tail
 -- Scheme Procedure: append-reverse! rev-head tail
     Reverse REV-HEAD, append TAIL to it, and return the result.  This
     is equivalent to ‘(append (reverse REV-HEAD) TAIL)’, but its
     implementation is more efficient.

          (append-reverse '(1 2 3) '(4 5 6)) ⇒ (3 2 1 4 5 6)

     ‘append-reverse!’ may modify REV-HEAD in order to produce the
     result.

 -- Scheme Procedure: zip lst1 lst2 ...
     Return a list as long as the shortest of the argument lists, where
     each element is a list.  The first list contains the first elements
     of the argument lists, the second list contains the second
     elements, and so on.

 -- Scheme Procedure: unzip1 lst
 -- Scheme Procedure: unzip2 lst
 -- Scheme Procedure: unzip3 lst
 -- Scheme Procedure: unzip4 lst
 -- Scheme Procedure: unzip5 lst
     ‘unzip1’ takes a list of lists, and returns a list containing the
     first elements of each list, ‘unzip2’ returns two lists, the first
     containing the first elements of each lists and the second
     containing the second elements of each lists, and so on.

 -- Scheme Procedure: count pred lst1 ... lstN
     Return a count of the number of times PRED returns true when called
     on elements from the given lists.

     PRED is called with N parameters ‘(PRED ELEM1 ... ELEMN)’, each
     element being from the corresponding LST1 ... LSTN.  The first call
     is with the first element of each list, the second with the second
     element from each, and so on.

     Counting stops when the end of the shortest list is reached.  At
     least one list must be non-circular.


File: guile.info,  Node: SRFI-1 Fold and Map,  Next: SRFI-1 Filtering and Partitioning,  Prev: SRFI-1 Length Append etc,  Up: SRFI-1

6.4.3.5 Fold, Unfold & Map
..........................

 -- Scheme Procedure: fold proc init lst1 ... lstN
 -- Scheme Procedure: fold-right proc init lst1 ... lstN
     Apply PROC to the elements of LST1 ... LSTN to build a result, and
     return that result.

     Each PROC call is ‘(PROC ELEM1 ... ELEMN PREVIOUS)’, where ELEM1 is
     from LST1, through ELEMN from LSTN.  PREVIOUS is the return from
     the previous call to PROC, or the given INIT for the first call.
     If any list is empty, just INIT is returned.

     ‘fold’ works through the list elements from first to last.  The
     following shows a list reversal and the calls it makes,

          (fold cons '() '(1 2 3))

          (cons 1 '())
          (cons 2 '(1))
          (cons 3 '(2 1)
          ⇒ (3 2 1)

     ‘fold-right’ works through the list elements from last to first,
     ie. from the right.  So for example the following finds the longest
     string, and the last among equal longest,

          (fold-right (lambda (str prev)
                        (if (> (string-length str) (string-length prev))
                            str
                            prev))
                      ""
                      '("x" "abc" "xyz" "jk"))
          ⇒ "xyz"

     If LST1 through LSTN have different lengths, ‘fold’ stops when the
     end of the shortest is reached; ‘fold-right’ commences at the last
     element of the shortest.  Ie. elements past the length of the
     shortest are ignored in the other LSTs.  At least one LST must be
     non-circular.

     ‘fold’ should be preferred over ‘fold-right’ if the order of
     processing doesn't matter, or can be arranged either way, since
     ‘fold’ is a little more efficient.

     The way ‘fold’ builds a result from iterating is quite general, it
     can do more than other iterations like say ‘map’ or ‘filter’.  The
     following for example removes adjacent duplicate elements from a
     list,

          (define (delete-adjacent-duplicates lst)
            (fold-right (lambda (elem ret)
                          (if (equal? elem (first ret))
                              ret
                              (cons elem ret)))
                        (list (last lst))
                        lst))
          (delete-adjacent-duplicates '(1 2 3 3 4 4 4 5))
          ⇒ (1 2 3 4 5)

     Clearly the same sort of thing can be done with a ‘for-each’ and a
     variable in which to build the result, but a self-contained PROC
     can be re-used in multiple contexts, where a ‘for-each’ would have
     to be written out each time.

 -- Scheme Procedure: pair-fold proc init lst1 ... lstN
 -- Scheme Procedure: pair-fold-right proc init lst1 ... lstN
     The same as ‘fold’ and ‘fold-right’, but apply PROC to the pairs of
     the lists instead of the list elements.

 -- Scheme Procedure: reduce proc default lst
 -- Scheme Procedure: reduce-right proc default lst
     ‘reduce’ is a variant of ‘fold’, where the first call to PROC is on
     two elements from LST, rather than one element and a given initial
     value.

     If LST is empty, ‘reduce’ returns DEFAULT (this is the only use for
     DEFAULT).  If LST has just one element then that's the return
     value.  Otherwise PROC is called on the elements of LST.

     Each PROC call is ‘(PROC ELEM PREVIOUS)’, where ELEM is from LST
     (the second and subsequent elements of LST), and PREVIOUS is the
     return from the previous call to PROC.  The first element of LST is
     the PREVIOUS for the first call to PROC.

     For example, the following adds a list of numbers, the calls made
     to ‘+’ are shown.  (Of course ‘+’ accepts multiple arguments and
     can add a list directly, with ‘apply’.)

          (reduce + 0 '(5 6 7)) ⇒ 18

          (+ 6 5)  ⇒ 11
          (+ 7 11) ⇒ 18

     ‘reduce’ can be used instead of ‘fold’ where the INIT value is an
     "identity", meaning a value which under PROC doesn't change the
     result, in this case 0 is an identity since ‘(+ 5 0)’ is just 5.
     ‘reduce’ avoids that unnecessary call.

     ‘reduce-right’ is a similar variation on ‘fold-right’, working from
     the end (ie. the right) of LST.  The last element of LST is the
     PREVIOUS for the first call to PROC, and the ELEM values go from
     the second last.

     ‘reduce’ should be preferred over ‘reduce-right’ if the order of
     processing doesn't matter, or can be arranged either way, since
     ‘reduce’ is a little more efficient.

 -- Scheme Procedure: unfold p f g seed [tail-gen]
     ‘unfold’ is defined as follows:

          (unfold p f g seed) =
             (if (p seed) (tail-gen seed)
                 (cons (f seed)
                       (unfold p f g (g seed))))

     P
          Determines when to stop unfolding.

     F
          Maps each seed value to the corresponding list element.

     G
          Maps each seed value to next seed valu.

     SEED
          The state value for the unfold.

     TAIL-GEN
          Creates the tail of the list; defaults to ‘(lambda (x) '())’.

     G produces a series of seed values, which are mapped to list
     elements by F.  These elements are put into a list in left-to-right
     order, and P tells when to stop unfolding.

 -- Scheme Procedure: unfold-right p f g seed [tail]
     Construct a list with the following loop.

          (let lp ((seed seed) (lis tail))
             (if (p seed) lis
                 (lp (g seed)
                     (cons (f seed) lis))))

     P
          Determines when to stop unfolding.

     F
          Maps each seed value to the corresponding list element.

     G
          Maps each seed value to next seed valu.

     SEED
          The state value for the unfold.

     TAIL-GEN
          Creates the tail of the list; defaults to ‘(lambda (x) '())’.

 -- Scheme Procedure: map f lst1 lst2 ...
     Map the procedure over the list(s) LST1, LST2, ... and return a
     list containing the results of the procedure applications.  This
     procedure is extended with respect to R5RS, because the argument
     lists may have different lengths.  The result list will have the
     same length as the shortest argument lists.  The order in which F
     will be applied to the list element(s) is not specified.

 -- Scheme Procedure: for-each f lst1 lst2 ...
     Apply the procedure F to each pair of corresponding elements of the
     list(s) LST1, LST2, ....  The return value is not specified.  This
     procedure is extended with respect to R5RS, because the argument
     lists may have different lengths.  The shortest argument list
     determines the number of times F is called.  F will be applied to
     the list elements in left-to-right order.

 -- Scheme Procedure: append-map f lst1 lst2 ...
 -- Scheme Procedure: append-map! f lst1 lst2 ...
     Equivalent to

          (apply append (map f clist1 clist2 ...))

     and

          (apply append! (map f clist1 clist2 ...))

     Map F over the elements of the lists, just as in the ‘map’
     function.  However, the results of the applications are appended
     together to make the final result.  ‘append-map’ uses ‘append’ to
     append the results together; ‘append-map!’ uses ‘append!’.

     The dynamic order in which the various applications of F are made
     is not specified.

 -- Scheme Procedure: map! f lst1 lst2 ...
     Linear-update variant of ‘map’ - ‘map!’ is allowed, but not
     required, to alter the cons cells of LST1 to construct the result
     list.

     The dynamic order in which the various applications of F are made
     is not specified.  In the n-ary case, LST2, LST3, ... must have at
     least as many elements as LST1.

 -- Scheme Procedure: pair-for-each f lst1 lst2 ...
     Like ‘for-each’, but applies the procedure F to the pairs from
     which the argument lists are constructed, instead of the list
     elements.  The return value is not specified.

 -- Scheme Procedure: filter-map f lst1 lst2 ...
     Like ‘map’, but only results from the applications of F which are
     true are saved in the result list.

