diff options
author | Marius Vollmer <mvo@zagadka.de> | 2004-08-02 12:29:00 +0000 |
---|---|---|
committer | Marius Vollmer <mvo@zagadka.de> | 2004-08-02 12:29:00 +0000 |
commit | 07d83abe7b8b617e4bb70a08efc0c0f6999fa0cc (patch) | |
tree | 34c8a7b9d98000169379038be8551ed44c0bdb83 /doc/ref | |
parent | 237be238424f1b6d130799ad931ba6fa8504a97c (diff) | |
download | guile-07d83abe7b8b617e4bb70a08efc0c0f6999fa0cc.tar.gz |
* scheme-binding.texi: Renamed to api-binding.texi.
* scheme-compound.texi: Renamed to api-compound.texi.
* scheme-control.texi: Renamed to api-control.texi.
* scheme-data.texi: Renamed to api-data.texi.
* scheme-debug.texi: Renamed to api-debug.texi.
* deprecated.texi: Renamed to api-deprecated.texi.
* scheme-evaluation.texi: Renamed to api-evaluation.texi.
* ref-init.texi: Renamed to api-init.texi.
* scheme-io.texi: Renamed to api-io.texi.
* scheme-memory.texi: Renamed to api-memory.texi.
* scheme-modules.texi: Renamed to api-modules.texi.
* scheme-options.texi: Renamed to api-options.texi.
* scm.texi: Renamed to api-overview.texi.
* scheme-procedures.texi: Renamed to api-procedures.texi.
* scheme-scheduling.texi: Renamed to api-scheduling.texi.
* scheme-scm.texi: Renamed to api-scm.texi.
* scheme-smobs.texi: Renamed to api-smobs.texi.
* scheme-snarf.texi: Renamed to api-snarf.texi.
* scheme-translation.texi: Renamed to api-translation.texi.
* scheme-utility.texi: Renamed to api-utility.texi.
* debugging.texi: Renamed to scheme-debugging.texi.
* scripts.texi: Renamed to scheme-scripts.texi.
* program.texi: Renamed to libguile-program.texi.
Diffstat (limited to 'doc/ref')
45 files changed, 16805 insertions, 45 deletions
diff --git a/doc/ref/Makefile.am b/doc/ref/Makefile.am index 825cbcb0b..4964ed53d 100644 --- a/doc/ref/Makefile.am +++ b/doc/ref/Makefile.am @@ -27,24 +27,24 @@ guile_TEXINFOS = preface.texi \ intro.texi \ libguile-program.texi \ scheme-intro.texi \ - scheme-scm.texi \ - scheme-snarf.texi \ - scheme-smobs.texi \ + api-scm.texi \ + api-snarf.texi \ + api-smobs.texi \ scheme-ideas.texi \ - scheme-data.texi \ - scheme-procedures.texi \ - scheme-utility.texi \ - scheme-binding.texi \ - scheme-control.texi \ - scheme-io.texi \ - scheme-evaluation.texi \ - scheme-memory.texi \ - scheme-modules.texi \ - scheme-scheduling.texi \ - scheme-options.texi \ - scheme-translation.texi \ - scheme-debug.texi \ - deprecated.texi \ + api-data.texi \ + api-procedures.texi \ + api-utility.texi \ + api-binding.texi \ + api-control.texi \ + api-io.texi \ + api-evaluation.texi \ + api-memory.texi \ + api-modules.texi \ + api-scheduling.texi \ + api-options.texi \ + api-translation.texi \ + api-debug.texi \ + api-deprecated.texi \ scheme-reading.texi \ scheme-indices.texi \ slib.texi \ @@ -52,17 +52,17 @@ guile_TEXINFOS = preface.texi \ expect.texi \ scsh.texi \ tcltk.texi \ - scripts.texi \ + scheme-scripts.texi \ gh.texi \ - scm.texi \ - debugging.texi \ + api-overview.texi \ + scheme-debugging.texi \ indices.texi \ script-getopt.texi \ data-rep.texi \ repl-modules.texi \ srfi-modules.texi \ misc-modules.texi \ - scheme-compound.texi \ + api-compound.texi \ autoconf.texi \ autoconf-macros.texi \ tools.texi \ @@ -72,7 +72,7 @@ guile_TEXINFOS = preface.texi \ libguile-snarf.texi \ libguile-linking.texi \ libguile-extensions.texi \ - ref-init.texi \ + api-init.texi \ mod-getopt-long.texi ETAGS_ARGS = $(info_TEXINFOS) $(guile_TEXINFOS) diff --git a/doc/ref/api-binding.texi b/doc/ref/api-binding.texi new file mode 100644 index 000000000..b42f5567f --- /dev/null +++ b/doc/ref/api-binding.texi @@ -0,0 +1,283 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Binding Constructs +@section Definitions and Variable Bindings + +@c FIXME::martin: Review me! + +Scheme supports the definition of variables in different contexts. +Variables can be defined at the top level, so that they are visible in +the entire program, and variables can be defined locally to procedures +and expressions. This is important for modularity and data abstraction. + +@menu +* Top Level:: Top level variable definitions. +* Local Bindings:: Local variable bindings. +* Internal Definitions:: Internal definitions. +* Binding Reflection:: Querying variable bindings. +@end menu + + +@node Top Level +@subsection Top Level Variable Definitions + +@cindex variable definition + +On the top level of a program (i.e. when not inside the body of a +procedure definition or a @code{let}, @code{let*} or @code{letrec} +expression), a definition of the form + +@lisp +(define a @var{value}) +@end lisp + +@noindent +defines a variable called @code{a} and sets it to the value @var{value}. + +If the variable already exists, because it has already been created by a +previous @code{define} expression with the same name, its value is +simply changed to the new @var{value}. In this case, then, the above +form is completely equivalent to + +@lisp +(set! a @var{value}) +@end lisp + +@noindent +This equivalence means that @code{define} can be used interchangeably +with @code{set!} to change the value of variables at the top level of +the REPL or a Scheme source file. It is useful during interactive +development when reloading a Scheme file that you have modified, because +it allows the @code{define} expressions in that file to work as expected +both the first time that the file is loaded and on subsequent occasions. + +Note, though, that @code{define} and @code{set!} are not always +equivalent. For example, a @code{set!} is not allowed if the named +variable does not already exist, and the two expressions can behave +differently in the case where there are imported variables visible from +another module. + +@deffn {Scheme Syntax} define name value +Create a top level variable named @var{name} with value @var{value}. +If the named variable already exists, just change its value. The return +value of a @code{define} expression is unspecified. +@end deffn + +The C API equivalents of @code{define} are @code{scm_define} and +@code{scm_c_define}, which differ from each other in whether the +variable name is specified as a @code{SCM} symbol or as a +null-terminated C string. + +@deffn {C Function} scm_define (sym, value) +@deffnx {C Function} scm_c_define (const char *name, value) +C equivalents of @code{define}, with variable name specified either by +@var{sym}, a symbol, or by @var{name}, a null-terminated C string. Both +variants return the new or preexisting variable object. +@end deffn + +@code{define} (when it occurs at top level), @code{scm_define} and +@code{scm_c_define} all create or set the value of a variable in the top +level environment of the current module. If there was not already a +variable with the specified name belonging to the current module, but a +similarly named variable from another module was visible through having +been imported, the newly created variable in the current module will +shadow the imported variable, such that the imported variable is no +longer visible. + +Attention: Scheme definitions inside local binding constructs +(@pxref{Local Bindings}) act differently (@pxref{Internal Definitions}). + + +@node Local Bindings +@subsection Local Variable Bindings + +@c FIXME::martin: Review me! + +@cindex local bindings +@cindex local variables + +As opposed to definitions at the top level, which are visible in the +whole program (or current module, when Guile modules are used), it is +also possible to define variables which are only visible in a +well-defined part of the program. Normally, this part of a program +will be a procedure or a subexpression of a procedure. + +With the constructs for local binding (@code{let}, @code{let*} and +@code{letrec}), the Scheme language has a block structure like most +other programming languages since the days of @sc{Algol 60}. Readers +familiar to languages like C or Java should already be used to this +concept, but the family of @code{let} expressions has a few properties +which are well worth knowing. + +The first local binding construct is @code{let}. The other constructs +@code{let*} and @code{letrec} are specialized versions for usage where +using plain @code{let} is a bit inconvenient. + +@deffn syntax let bindings body +@var{bindings} has the form + +@lisp +((@var{variable1} @var{init1}) @dots{}) +@end lisp + +that is zero or more two-element lists of a variable and an arbitrary +expression each. All @var{variable} names must be distinct. + +A @code{let} expression is evaluated as follows. + +@itemize @bullet +@item +All @var{init} expressions are evaluated. + +@item +New storage is allocated for the @var{variables}. + +@item +The values of the @var{init} expressions are stored into the variables. + +@item +The expressions in @var{body} are evaluated in order, and the value of +the last expression is returned as the value of the @code{let} +expression. + +@item +The storage for the @var{variables} is freed. +@end itemize + +The @var{init} expressions are not allowed to refer to any of the +@var{variables}. +@end deffn + +@deffn syntax let* bindings body +Similar to @code{let}, but the variable bindings are performed +sequentially, that means that all @var{init} expression are allowed to +use the variables defined on their left in the binding list. + +A @code{let*} expression can always be expressed with nested @code{let} +expressions. + +@lisp +(let* ((a 1) (b a)) + b) +@equiv{} +(let ((a 1)) + (let ((b a)) + b)) +@end lisp +@end deffn + +@deffn syntax letrec bindings body +Similar to @code{let}, but it is possible to refer to the @var{variable} +from lambda expression created in any of the @var{inits}. That is, +procedures created in the @var{init} expression can recursively refer to +the defined variables. + +@lisp +(letrec ((even? + (lambda (n) + (if (zero? n) + #t + (odd? (- n 1))))) + (odd? + (lambda (n) + (if (zero? n) + #f + (even? (- n 1)))))) + (even? 88)) +@result{} +#t +@end lisp +@end deffn + +There is also an alternative form of the @code{let} form, which is used +for expressing iteration. Because of the use as a looping construct, +this form (the @dfn{named let}) is documented in the section about +iteration (@pxref{while do, Iteration}) + +@node Internal Definitions +@subsection Internal definitions + +@c FIXME::martin: Review me! + +A @code{define} form which appears inside the body of a @code{lambda}, +@code{let}, @code{let*}, @code{letrec} or equivalent expression is +called an @dfn{internal definition}. An internal definition differs +from a top level definition (@pxref{Top Level}), because the definition +is only visible inside the complete body of the enclosing form. Let us +examine the following example. + +@lisp +(let ((frumble "froz")) + (define banana (lambda () (apple 'peach))) + (define apple (lambda (x) x)) + (banana)) +@result{} +peach +@end lisp + +Here the enclosing form is a @code{let}, so the @code{define}s in the +@code{let}-body are internal definitions. Because the scope of the +internal definitions is the @strong{complete} body of the +@code{let}-expression, the @code{lambda}-expression which gets bound +to the variable @code{banana} may refer to the variable @code{apple}, +even though it's definition appears lexically @emph{after} the definition +of @code{banana}. This is because a sequence of internal definition +acts as if it were a @code{letrec} expression. + +@lisp +(let () + (define a 1) + (define b 2) + (+ a b)) +@end lisp + +@noindent +is equivalent to + +@lisp +(let () + (letrec ((a 1) (b 2)) + (+ a b))) +@end lisp + +Another noteworthy difference to top level definitions is that within +one group of internal definitions all variable names must be distinct. +That means where on the top level a second define for a given variable +acts like a @code{set!}, an exception is thrown for internal definitions +with duplicate bindings. + +@c FIXME::martin: The following is required by R5RS, but Guile does not +@c signal an error. Document it anyway, saying that Guile is sloppy? + +@c Internal definitions are only allowed at the beginning of the body of an +@c enclosing expression. They may not be mixed with other expressions. + +@c @lisp +@c (let () +@c (define a 1) +@c a +@c (define b 2) +@c b) +@c @end lisp + +@node Binding Reflection +@subsection Querying variable bindings + +Guile provides a procedure for checking whether a symbol is bound in the +top level environment. + +@c NJFIXME explain [env] +@deffn {Scheme Procedure} defined? sym [env] +@deffnx {C Function} scm_defined_p (sym, env) +Return @code{#t} if @var{sym} is defined in the lexical environment @var{env}. When @var{env} is not specified, look in the top-level environment as defined by the current module. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/api-compound.texi b/doc/ref/api-compound.texi new file mode 100644 index 000000000..f117e1cfc --- /dev/null +++ b/doc/ref/api-compound.texi @@ -0,0 +1,2530 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Compound Data Types +@section Compound Data Types + +This chapter describes Guile's compound data types. By @dfn{compound} +we mean that the primary purpose of these data types is to act as +containers for other kinds of data (including other compound objects). +For instance, a (non-uniform) vector with length 5 is a container that +can hold five arbitrary Scheme objects. + +The various kinds of container object differ from each other in how +their memory is allocated, how they are indexed, and how particular +values can be looked up within them. + +@menu +* Pairs:: Scheme's basic building block. +* Lists:: Special list functions supported by Guile. +* Vectors:: One-dimensional arrays of Scheme objects. +* Records:: +* Structures:: +* Arrays:: Arrays of values. +* Dictionary Types:: About dictionary types in general. +* Association Lists:: List-based dictionaries. +* Hash Tables:: Table-based dictionaries. +@end menu + + +@node Pairs +@subsection Pairs +@tpindex Pairs + +Pairs are used to combine two Scheme objects into one compound object. +Hence the name: A pair stores a pair of objects. + +The data type @dfn{pair} is extremely important in Scheme, just like in +any other Lisp dialect. The reason is that pairs are not only used to +make two values available as one object, but that pairs are used for +constructing lists of values. Because lists are so important in Scheme, +they are described in a section of their own (@pxref{Lists}). + +Pairs can literally get entered in source code or at the REPL, in the +so-called @dfn{dotted list} syntax. This syntax consists of an opening +parentheses, the first element of the pair, a dot, the second element +and a closing parentheses. The following example shows how a pair +consisting of the two numbers 1 and 2, and a pair containing the symbols +@code{foo} and @code{bar} can be entered. It is very important to write +the whitespace before and after the dot, because otherwise the Scheme +parser would not be able to figure out where to split the tokens. + +@lisp +(1 . 2) +(foo . bar) +@end lisp + +But beware, if you want to try out these examples, you have to +@dfn{quote} the expressions. More information about quotation is +available in the section (REFFIXME). The correct way to try these +examples is as follows. + +@lisp +'(1 . 2) +@result{} +(1 . 2) +'(foo . bar) +@result{} +(foo . bar) +@end lisp + +A new pair is made by calling the procedure @code{cons} with two +arguments. Then the argument values are stored into a newly allocated +pair, and the pair is returned. The name @code{cons} stands for +"construct". Use the procedure @code{pair?} to test whether a +given Scheme object is a pair or not. + +@rnindex cons +@deffn {Scheme Procedure} cons x y +@deffnx {C Function} scm_cons (x, y) +Return a newly allocated pair whose car is @var{x} and whose +cdr is @var{y}. The pair is guaranteed to be different (in the +sense of @code{eq?}) from every previously existing object. +@end deffn + +@rnindex pair? +@deffn {Scheme Procedure} pair? x +@deffnx {C Function} scm_pair_p (x) +Return @code{#t} if @var{x} is a pair; otherwise return +@code{#f}. +@end deffn + +The two parts of a pair are traditionally called @dfn{car} and +@dfn{cdr}. They can be retrieved with procedures of the same name +(@code{car} and @code{cdr}), and can be modified with the procedures +@code{set-car!} and @code{set-cdr!}. Since a very common operation in +Scheme programs is to access the car of a pair, or the car of the cdr of +a pair, etc., the procedures called @code{caar}, @code{cadr} and so on +are also predefined. + +@rnindex car +@rnindex cdr +@deffn {Scheme Procedure} car pair +@deffnx {Scheme Procedure} cdr pair +Return the car or the cdr of @var{pair}, respectively. +@end deffn + +@deffn {Scheme Procedure} caar pair +@deffnx {Scheme Procedure} cadr pair @dots{} +@deffnx {Scheme Procedure} cdddar pair +@deffnx {Scheme Procedure} cddddr pair +These procedures are compositions of @code{car} and @code{cdr}, where +for example @code{caddr} could be defined by + +@lisp +(define caddr (lambda (x) (car (cdr (cdr x))))) +@end lisp +@end deffn + +@rnindex set-car! +@deffn {Scheme Procedure} set-car! pair value +@deffnx {C Function} scm_set_car_x (pair, value) +Stores @var{value} in the car field of @var{pair}. The value returned +by @code{set-car!} is unspecified. +@end deffn + +@rnindex set-cdr! +@deffn {Scheme Procedure} set-cdr! pair value +@deffnx {C Function} scm_set_cdr_x (pair, value) +Stores @var{value} in the cdr field of @var{pair}. The value returned +by @code{set-cdr!} is unspecified. +@end deffn + + +@node Lists +@subsection Lists +@tpindex Lists + +A very important data type in Scheme---as well as in all other Lisp +dialects---is the data type @dfn{list}.@footnote{Strictly speaking, +Scheme does not have a real datatype @dfn{list}. Lists are made up of +@dfn{chained pairs}, and only exist by definition---a list is a chain +of pairs which looks like a list.} + +This is the short definition of what a list is: + +@itemize @bullet +@item +Either the empty list @code{()}, + +@item +or a pair which has a list in its cdr. +@end itemize + +@c FIXME::martin: Describe the pair chaining in more detail. + +@c FIXME::martin: What is a proper, what an improper list? +@c What is a circular list? + +@c FIXME::martin: Maybe steal some graphics from the Elisp reference +@c manual? + +@menu +* List Syntax:: Writing literal lists. +* List Predicates:: Testing lists. +* List Constructors:: Creating new lists. +* List Selection:: Selecting from lists, getting their length. +* Append/Reverse:: Appending and reversing lists. +* List Modification:: Modifying existing lists. +* List Searching:: Searching for list elements +* List Mapping:: Applying procedures to lists. +@end menu + +@node List Syntax +@subsubsection List Read Syntax + +The syntax for lists is an opening parentheses, then all the elements of +the list (separated by whitespace) and finally a closing +parentheses.@footnote{Note that there is no separation character between +the list elements, like a comma or a semicolon.}. + +@lisp +(1 2 3) ; @r{a list of the numbers 1, 2 and 3} +("foo" bar 3.1415) ; @r{a string, a symbol and a real number} +() ; @r{the empty list} +@end lisp + +The last example needs a bit more explanation. A list with no elements, +called the @dfn{empty list}, is special in some ways. It is used for +terminating lists by storing it into the cdr of the last pair that makes +up a list. An example will clear that up: + +@lisp +(car '(1)) +@result{} +1 +(cdr '(1)) +@result{} +() +@end lisp + +This example also shows that lists have to be quoted (REFFIXME) when +written, because they would otherwise be mistakingly taken as procedure +applications (@pxref{Simple Invocation}). + + +@node List Predicates +@subsubsection List Predicates + +Often it is useful to test whether a given Scheme object is a list or +not. List-processing procedures could use this information to test +whether their input is valid, or they could do different things +depending on the datatype of their arguments. + +@rnindex list? +@deffn {Scheme Procedure} list? x +@deffnx {C Function} scm_list_p (x) +Return @code{#t} iff @var{x} is a proper list, else @code{#f}. +@end deffn + +The predicate @code{null?} is often used in list-processing code to +tell whether a given list has run out of elements. That is, a loop +somehow deals with the elements of a list until the list satisfies +@code{null?}. Then, the algorithm terminates. + +@rnindex null? +@deffn {Scheme Procedure} null? x +@deffnx {C Function} scm_null_p (x) +Return @code{#t} iff @var{x} is the empty list, else @code{#f}. +@end deffn + +@node List Constructors +@subsubsection List Constructors + +This section describes the procedures for constructing new lists. +@code{list} simply returns a list where the elements are the arguments, +@code{cons*} is similar, but the last argument is stored in the cdr of +the last pair of the list. + +@c C Function scm_list(rest) used to be documented here, but it's a +@c no-op since it does nothing but return the list the caller must +@c have already created. +@c +@deffn {Scheme Procedure} list elem1 @dots{} elemN +@deffnx {C Function} scm_list_1 (elem1) +@deffnx {C Function} scm_list_2 (elem1, elem2) +@deffnx {C Function} scm_list_3 (elem1, elem2, elem3) +@deffnx {C Function} scm_list_4 (elem1, elem2, elem3, elem4) +@deffnx {C Function} scm_list_5 (elem1, elem2, elem3, elem4, elem5) +@deffnx {C Function} scm_list_n (elem1, @dots{}, elemN, @nicode{SCM_UNDEFINED}) +@rnindex list +Return a new list containing elements @var{elem1} to @var{elemN}. + +@code{scm_list_n} takes a variable number of arguments, terminated by +the special @code{SCM_UNDEFINED}. That final @code{SCM_UNDEFINED} is +not included in the list. None of @var{elem1} to @var{elemN} can +themselves be @code{SCM_UNDEFINED}, or @code{scm_list_n} will +terminate at that point. +@end deffn + +@c C Function scm_cons_star(arg1,rest) used to be documented here, +@c but it's not really a useful interface, since it expects the +@c caller to have already consed up all but the first argument +@c already. +@c +@deffn {Scheme Procedure} cons* arg1 arg2 @dots{} +Like @code{list}, but the last arg provides the tail of the +constructed list, returning @code{(cons @var{arg1} (cons +@var{arg2} (cons @dots{} @var{argn})))}. Requires at least one +argument. If given one argument, that argument is returned as +result. This function is called @code{list*} in some other +Schemes and in Common LISP. +@end deffn + +@deffn {Scheme Procedure} list-copy lst +@deffnx {C Function} scm_list_copy (lst) +Return a (newly-created) copy of @var{lst}. +@end deffn + +@deffn {Scheme Procedure} make-list n [init] +Create a list containing of @var{n} elements, where each element is +initialized to @var{init}. @var{init} defaults to the empty list +@code{()} if not given. +@end deffn + +Note that @code{list-copy} only makes a copy of the pairs which make up +the spine of the lists. The list elements are not copied, which means +that modifying the elements of the new list also modifies the elements +of the old list. On the other hand, applying procedures like +@code{set-cdr!} or @code{delv!} to the new list will not alter the old +list. If you also need to copy the list elements (making a deep copy), +use the procedure @code{copy-tree} (@pxref{Copying}). + +@node List Selection +@subsubsection List Selection + +These procedures are used to get some information about a list, or to +retrieve one or more elements of a list. + +@rnindex length +@deffn {Scheme Procedure} length lst +@deffnx {C Function} scm_length (lst) +Return the number of elements in list @var{lst}. +@end deffn + +@deffn {Scheme Procedure} last-pair lst +@deffnx {C Function} scm_last_pair (lst) +Return a pointer to the last pair in @var{lst}, signalling an error if +@var{lst} is circular. +@end deffn + +@rnindex list-ref +@deffn {Scheme Procedure} list-ref list k +@deffnx {C Function} scm_list_ref (list, k) +Return the @var{k}th element from @var{list}. +@end deffn + +@rnindex list-tail +@deffn {Scheme Procedure} list-tail lst k +@deffnx {Scheme Procedure} list-cdr-ref lst k +@deffnx {C Function} scm_list_tail (lst, k) +Return the "tail" of @var{lst} beginning with its @var{k}th element. +The first element of the list is considered to be element 0. + +@code{list-tail} and @code{list-cdr-ref} are identical. It may help to +think of @code{list-cdr-ref} as accessing the @var{k}th cdr of the list, +or returning the results of cdring @var{k} times down @var{lst}. +@end deffn + +@deffn {Scheme Procedure} list-head lst k +@deffnx {C Function} scm_list_head (lst, k) +Copy the first @var{k} elements from @var{lst} into a new list, and +return it. +@end deffn + +@node Append/Reverse +@subsubsection Append and Reverse + +@code{append} and @code{append!} are used to concatenate two or more +lists in order to form a new list. @code{reverse} and @code{reverse!} +return lists with the same elements as their arguments, but in reverse +order. The procedure variants with an @code{!} directly modify the +pairs which form the list, whereas the other procedures create new +pairs. This is why you should be careful when using the side-effecting +variants. + +@rnindex append +@deffn {Scheme Procedure} append lst1 @dots{} lstN +@deffnx {Scheme Procedure} append! lst1 @dots{} lstN +@deffnx {C Function} scm_append (lstlst) +@deffnx {C Function} scm_append_x (lstlst) +Return a list comprising all the elements of lists @var{lst1} to +@var{lstN}. + +@lisp +(append '(x) '(y)) @result{} (x y) +(append '(a) '(b c d)) @result{} (a b c d) +(append '(a (b)) '((c))) @result{} (a (b) (c)) +@end lisp + +The last argument @var{lstN} may actually be any object; an improper +list results if the last argument is not a proper list. + +@lisp +(append '(a b) '(c . d)) @result{} (a b c . d) +(append '() 'a) @result{} a +@end lisp + +@code{append} doesn't modify the given lists, but the return may share +structure with the final @var{lstN}. @code{append!} modifies the +given lists to form its return. + +For @code{scm_append} and @code{scm_append_x}, @var{lstlst} is a list +of the list operands @var{lst1} @dots{} @var{lstN}. That @var{lstlst} +itself is not modified or used in the return. +@end deffn + +@rnindex reverse +@deffn {Scheme Procedure} reverse lst +@deffnx {Scheme Procedure} reverse! lst [newtail] +@deffnx {C Function} scm_reverse (lst) +@deffnx {C Function} scm_reverse_x (lst, newtail) +Return a list comprising the elements of @var{lst}, in reverse order. + +@code{reverse} constructs a new list, @code{reverse!} modifies +@var{lst} in constructing its return. + +For @code{reverse!}, the optional @var{newtail} is appended to to the +result. @var{newtail} isn't reversed, it simply becomes the list +tail. For @code{scm_reverse_x}, the @var{newtail} parameter is +mandatory, but can be @code{SCM_EOL} if no further tail is required. +@end deffn + +@node List Modification +@subsubsection List Modification + +The following procedures modify an existing list, either by changing +elements of the list, or by changing the list structure itself. + +@deffn {Scheme Procedure} list-set! list k val +@deffnx {C Function} scm_list_set_x (list, k, val) +Set the @var{k}th element of @var{list} to @var{val}. +@end deffn + +@deffn {Scheme Procedure} list-cdr-set! list k val +@deffnx {C Function} scm_list_cdr_set_x (list, k, val) +Set the @var{k}th cdr of @var{list} to @var{val}. +@end deffn + +@deffn {Scheme Procedure} delq item lst +@deffnx {C Function} scm_delq (item, lst) +Return a newly-created copy of @var{lst} with elements +@code{eq?} to @var{item} removed. This procedure mirrors +@code{memq}: @code{delq} compares elements of @var{lst} against +@var{item} with @code{eq?}. +@end deffn + +@deffn {Scheme Procedure} delv item lst +@deffnx {C Function} scm_delv (item, lst) +Return a newly-created copy of @var{lst} with elements +@code{eqv?} to @var{item} removed. This procedure mirrors +@code{memv}: @code{delv} compares elements of @var{lst} against +@var{item} with @code{eqv?}. +@end deffn + +@deffn {Scheme Procedure} delete item lst +@deffnx {C Function} scm_delete (item, lst) +Return a newly-created copy of @var{lst} with elements +@code{equal?} to @var{item} removed. This procedure mirrors +@code{member}: @code{delete} compares elements of @var{lst} +against @var{item} with @code{equal?}. +@end deffn + +@deffn {Scheme Procedure} delq! item lst +@deffnx {Scheme Procedure} delv! item lst +@deffnx {Scheme Procedure} delete! item lst +@deffnx {C Function} scm_delq_x (item, lst) +@deffnx {C Function} scm_delv_x (item, lst) +@deffnx {C Function} scm_delete_x (item, lst) +These procedures are destructive versions of @code{delq}, @code{delv} +and @code{delete}: they modify the pointers in the existing @var{lst} +rather than creating a new list. Caveat evaluator: Like other +destructive list functions, these functions cannot modify the binding of +@var{lst}, and so cannot be used to delete the first element of +@var{lst} destructively. +@end deffn + +@deffn {Scheme Procedure} delq1! item lst +@deffnx {C Function} scm_delq1_x (item, lst) +Like @code{delq!}, but only deletes the first occurrence of +@var{item} from @var{lst}. Tests for equality using +@code{eq?}. See also @code{delv1!} and @code{delete1!}. +@end deffn + +@deffn {Scheme Procedure} delv1! item lst +@deffnx {C Function} scm_delv1_x (item, lst) +Like @code{delv!}, but only deletes the first occurrence of +@var{item} from @var{lst}. Tests for equality using +@code{eqv?}. See also @code{delq1!} and @code{delete1!}. +@end deffn + +@deffn {Scheme Procedure} delete1! item lst +@deffnx {C Function} scm_delete1_x (item, lst) +Like @code{delete!}, but only deletes the first occurrence of +@var{item} from @var{lst}. Tests for equality using +@code{equal?}. See also @code{delq1!} and @code{delv1!}. +@end deffn + +@deffn {Scheme Procedure} filter pred lst +@deffnx {Scheme Procedure} filter! pred lst +Return a list containing all elements from @var{lst} which satisfy the +predicate @var{pred}. The elements in the result list have the same +order as in @var{lst}. The order in which @var{pred} is applied to +the list elements is not specified. + +@code{filter!} is allowed, but not required to modify the structure of +@end deffn + +@node List Searching +@subsubsection List Searching + +The following procedures search lists for particular elements. They use +different comparison predicates for comparing list elements with the +object to be searched. When they fail, they return @code{#f}, otherwise +they return the sublist whose car is equal to the search object, where +equality depends on the equality predicate used. + +@rnindex memq +@deffn {Scheme Procedure} memq x lst +@deffnx {C Function} scm_memq (x, lst) +Return the first sublist of @var{lst} whose car is @code{eq?} +to @var{x} where the sublists of @var{lst} are the non-empty +lists returned by @code{(list-tail @var{lst} @var{k})} for +@var{k} less than the length of @var{lst}. If @var{x} does not +occur in @var{lst}, then @code{#f} (not the empty list) is +returned. +@end deffn + +@rnindex memv +@deffn {Scheme Procedure} memv x lst +@deffnx {C Function} scm_memv (x, lst) +Return the first sublist of @var{lst} whose car is @code{eqv?} +to @var{x} where the sublists of @var{lst} are the non-empty +lists returned by @code{(list-tail @var{lst} @var{k})} for +@var{k} less than the length of @var{lst}. If @var{x} does not +occur in @var{lst}, then @code{#f} (not the empty list) is +returned. +@end deffn + +@rnindex member +@deffn {Scheme Procedure} member x lst +@deffnx {C Function} scm_member (x, lst) +Return the first sublist of @var{lst} whose car is +@code{equal?} to @var{x} where the sublists of @var{lst} are +the non-empty lists returned by @code{(list-tail @var{lst} +@var{k})} for @var{k} less than the length of @var{lst}. If +@var{x} does not occur in @var{lst}, then @code{#f} (not the +empty list) is returned. +@end deffn + + +@node List Mapping +@subsubsection List Mapping + +List processing is very convenient in Scheme because the process of +iterating over the elements of a list can be highly abstracted. The +procedures in this section are the most basic iterating procedures for +lists. They take a procedure and one or more lists as arguments, and +apply the procedure to each element of the list. They differ in their +return value. + +@rnindex map +@c begin (texi-doc-string "guile" "map") +@deffn {Scheme Procedure} map proc arg1 arg2 @dots{} +@deffnx {Scheme Procedure} map-in-order proc arg1 arg2 @dots{} +@deffnx {C Function} scm_map (proc, arg1, args) +Apply @var{proc} to each element of the list @var{arg1} (if only two +arguments are given), or to the corresponding elements of the argument +lists (if more than two arguments are given). The result(s) of the +procedure applications are saved and returned in a list. For +@code{map}, the order of procedure applications is not specified, +@code{map-in-order} applies the procedure from left to right to the list +elements. +@end deffn + +@rnindex for-each +@c begin (texi-doc-string "guile" "for-each") +@deffn {Scheme Procedure} for-each proc arg1 arg2 @dots{} +Like @code{map}, but the procedure is always applied from left to right, +and the result(s) of the procedure applications are thrown away. The +return value is not specified. +@end deffn + + +@node Vectors +@subsection Vectors +@tpindex Vectors + +Vectors are sequences of Scheme objects. Unlike lists, the length of a +vector, once the vector is created, cannot be changed. The advantage of +vectors over lists is that the time required to access one element of a vector +given its @dfn{position} (synonymous with @dfn{index}), a zero-origin number, +is constant, whereas lists have an access time linear to the position of the +accessed element in the list. + +Vectors can contain any kind of Scheme object; it is even possible to have +different types of objects in the same vector. For vectors containing +vectors, you may wish to use arrays, instead. Note, too, that some array +procedures operate happily on vectors (@pxref{Arrays}). + +@menu +* Vector Syntax:: Read syntax for vectors. +* Vector Creation:: Dynamic vector creation and validation. +* Vector Accessors:: Accessing and modifying vector contents. +@end menu + + +@node Vector Syntax +@subsubsection Read Syntax for Vectors + +Vectors can literally be entered in source code, just like strings, +characters or some of the other data types. The read syntax for vectors +is as follows: A sharp sign (@code{#}), followed by an opening +parentheses, all elements of the vector in their respective read syntax, +and finally a closing parentheses. The following are examples of the +read syntax for vectors; where the first vector only contains numbers +and the second three different object types: a string, a symbol and a +number in hexadecimal notation. + +@lisp +#(1 2 3) +#("Hello" foo #xdeadbeef) +@end lisp + +Like lists, vectors have to be quoted (REFFIXME): + +@lisp +'#(a b c) @result{} #(a b c) +@end lisp + +@node Vector Creation +@subsubsection Dynamic Vector Creation and Validation + +Instead of creating a vector implicitly by using the read syntax just +described, you can create a vector dynamically by calling one of the +@code{vector} and @code{list->vector} primitives with the list of Scheme +values that you want to place into a vector. The size of the vector +thus created is determined implicitly by the number of arguments given. + +@rnindex vector +@rnindex list->vector +@deffn {Scheme Procedure} vector . l +@deffnx {Scheme Procedure} list->vector l +@deffnx {C Function} scm_vector (l) +Return a newly allocated vector composed of the +given arguments. Analogous to @code{list}. + +@lisp +(vector 'a 'b 'c) @result{} #(a b c) +@end lisp +@end deffn + +(As an aside, an interesting implementation detail is that the Guile +reader reads the @code{#(@dots{})} syntax by reading everything but the +initial @code{#} as a @emph{list}, and then passing the list that +results to @code{list->vector}. Notice how neatly this fits with the +similarity between the read (and print) syntaxes for lists and vectors.) + +The inverse operation is @code{vector->list}: + +@rnindex vector->list +@deffn {Scheme Procedure} vector->list v +@deffnx {C Function} scm_vector_to_list (v) +Return a newly allocated list composed of the elements of @var{v}. + +@lisp +(vector->list '#(dah dah didah)) @result{} (dah dah didah) +(list->vector '(dididit dah)) @result{} #(dididit dah) +@end lisp +@end deffn + +To allocate a vector with an explicitly specified size, use +@code{make-vector}. With this primitive you can also specify an initial +value for the vector elements (the same value for all elements, that +is): + +@rnindex make-vector +@deffn {Scheme Procedure} make-vector k [fill] +@deffnx {C Function} scm_make_vector (k, fill) +Return a newly allocated vector of @var{k} elements. If a +second argument is given, then each position is initialized to +@var{fill}. Otherwise the initial contents of each position is +unspecified. +@end deffn + +To check whether an arbitrary Scheme value @emph{is} a vector, use the +@code{vector?} primitive: + +@rnindex vector? +@deffn {Scheme Procedure} vector? obj +@deffnx {C Function} scm_vector_p (obj) +Return @code{#t} if @var{obj} is a vector, otherwise return +@code{#f}. +@end deffn + + +@node Vector Accessors +@subsubsection Accessing and Modifying Vector Contents + +@code{vector-length} and @code{vector-ref} return information about a +given vector, respectively its size and the elements that are contained +in the vector. + +@rnindex vector-length +@deffn {Scheme Procedure} vector-length vector +@deffnx {C Function} scm_vector_length vector +Return the number of elements in @var{vector} as an exact integer. +@end deffn + +@rnindex vector-ref +@deffn {Scheme Procedure} vector-ref vector k +@deffnx {C Function} scm_vector_ref vector k +Return the contents of position @var{k} of @var{vector}. +@var{k} must be a valid index of @var{vector}. +@lisp +(vector-ref '#(1 1 2 3 5 8 13 21) 5) @result{} 8 +(vector-ref '#(1 1 2 3 5 8 13 21) + (let ((i (round (* 2 (acos -1))))) + (if (inexact? i) + (inexact->exact i) + i))) @result{} 13 +@end lisp +@end deffn + +A vector created by one of the dynamic vector constructor procedures +(@pxref{Vector Creation}) can be modified using the following +procedures. + +@emph{NOTE:} According to R5RS, it is an error to use any of these +procedures on a literally read vector, because such vectors should be +considered as constants. Currently, however, Guile does not detect this +error. + +@rnindex vector-set! +@deffn {Scheme Procedure} vector-set! vector k obj +@deffnx {C Function} scm_vector_set_x vector k obj +Store @var{obj} in position @var{k} of @var{vector}. +@var{k} must be a valid index of @var{vector}. +The value returned by @samp{vector-set!} is unspecified. +@lisp +(let ((vec (vector 0 '(2 2 2 2) "Anna"))) + (vector-set! vec 1 '("Sue" "Sue")) + vec) @result{} #(0 ("Sue" "Sue") "Anna") +@end lisp +@end deffn + +@rnindex vector-fill! +@deffn {Scheme Procedure} vector-fill! v fill +@deffnx {C Function} scm_vector_fill_x (v, fill) +Store @var{fill} in every position of @var{vector}. The value +returned by @code{vector-fill!} is unspecified. +@end deffn + +@deffn {Scheme Procedure} vector-move-left! vec1 start1 end1 vec2 start2 +@deffnx {C Function} scm_vector_move_left_x (vec1, start1, end1, vec2, start2) +Copy elements from @var{vec1}, positions @var{start1} to @var{end1}, +to @var{vec2} starting at position @var{start2}. @var{start1} and +@var{start2} are inclusive indices; @var{end1} is exclusive. + +@code{vector-move-left!} copies elements in leftmost order. +Therefore, in the case where @var{vec1} and @var{vec2} refer to the +same vector, @code{vector-move-left!} is usually appropriate when +@var{start1} is greater than @var{start2}. +@end deffn + +@deffn {Scheme Procedure} vector-move-right! vec1 start1 end1 vec2 start2 +@deffnx {C Function} scm_vector_move_right_x (vec1, start1, end1, vec2, start2) +Copy elements from @var{vec1}, positions @var{start1} to @var{end1}, +to @var{vec2} starting at position @var{start2}. @var{start1} and +@var{start2} are inclusive indices; @var{end1} is exclusive. + +@code{vector-move-right!} copies elements in rightmost order. +Therefore, in the case where @var{vec1} and @var{vec2} refer to the +same vector, @code{vector-move-right!} is usually appropriate when +@var{start1} is less than @var{start2}. +@end deffn + + +@node Records +@subsection Records + +A @dfn{record type} is a first class object representing a user-defined +data type. A @dfn{record} is an instance of a record type. + +@deffn {Scheme Procedure} record? obj +Return @code{#t} if @var{obj} is a record of any type and @code{#f} +otherwise. + +Note that @code{record?} may be true of any Scheme value; there is no +promise that records are disjoint with other Scheme types. +@end deffn + +@deffn {Scheme Procedure} make-record-type type-name field-names +Return a @dfn{record-type descriptor}, a value representing a new data +type disjoint from all others. The @var{type-name} argument must be a +string, but is only used for debugging purposes (such as the printed +representation of a record of the new type). The @var{field-names} +argument is a list of symbols naming the @dfn{fields} of a record of the +new type. It is an error if the list contains any duplicates. It is +unspecified how record-type descriptors are represented. +@end deffn + +@deffn {Scheme Procedure} record-constructor rtd [field-names] +Return a procedure for constructing new members of the type represented +by @var{rtd}. The returned procedure accepts exactly as many arguments +as there are symbols in the given list, @var{field-names}; these are +used, in order, as the initial values of those fields in a new record, +which is returned by the constructor procedure. The values of any +fields not named in that list are unspecified. The @var{field-names} +argument defaults to the list of field names in the call to +@code{make-record-type} that created the type represented by @var{rtd}; +if the @var{field-names} argument is provided, it is an error if it +contains any duplicates or any symbols not in the default list. +@end deffn + +@deffn {Scheme Procedure} record-predicate rtd +Return a procedure for testing membership in the type represented by +@var{rtd}. The returned procedure accepts exactly one argument and +returns a true value if the argument is a member of the indicated record +type; it returns a false value otherwise. +@end deffn + +@deffn {Scheme Procedure} record-accessor rtd field-name +Return a procedure for reading the value of a particular field of a +member of the type represented by @var{rtd}. The returned procedure +accepts exactly one argument which must be a record of the appropriate +type; it returns the current value of the field named by the symbol +@var{field-name} in that record. The symbol @var{field-name} must be a +member of the list of field-names in the call to @code{make-record-type} +that created the type represented by @var{rtd}. +@end deffn + +@deffn {Scheme Procedure} record-modifier rtd field-name +Return a procedure for writing the value of a particular field of a +member of the type represented by @var{rtd}. The returned procedure +accepts exactly two arguments: first, a record of the appropriate type, +and second, an arbitrary Scheme value; it modifies the field named by +the symbol @var{field-name} in that record to contain the given value. +The returned value of the modifier procedure is unspecified. The symbol +@var{field-name} must be a member of the list of field-names in the call +to @code{make-record-type} that created the type represented by +@var{rtd}. +@end deffn + +@deffn {Scheme Procedure} record-type-descriptor record +Return a record-type descriptor representing the type of the given +record. That is, for example, if the returned descriptor were passed to +@code{record-predicate}, the resulting predicate would return a true +value when passed the given record. Note that it is not necessarily the +case that the returned descriptor is the one that was passed to +@code{record-constructor} in the call that created the constructor +procedure that created the given record. +@end deffn + +@deffn {Scheme Procedure} record-type-name rtd +Return the type-name associated with the type represented by rtd. The +returned value is @code{eqv?} to the @var{type-name} argument given in +the call to @code{make-record-type} that created the type represented by +@var{rtd}. +@end deffn + +@deffn {Scheme Procedure} record-type-fields rtd +Return a list of the symbols naming the fields in members of the type +represented by @var{rtd}. The returned value is @code{equal?} to the +field-names argument given in the call to @code{make-record-type} that +created the type represented by @var{rtd}. +@end deffn + + +@node Structures +@subsection Structures +@tpindex Structures + +[FIXME: this is pasted in from Tom Lord's original guile.texi and should +be reviewed] + +A @dfn{structure type} is a first class user-defined data type. A +@dfn{structure} is an instance of a structure type. A structure type is +itself a structure. + +Structures are less abstract and more general than traditional records. +In fact, in Guile Scheme, records are implemented using structures. + +@menu +* Structure Concepts:: The structure of Structures +* Structure Layout:: Defining the layout of structure types +* Structure Basics:: make-, -ref and -set! procedures for structs +* Vtables:: Accessing type-specific data +@end menu + +@node Structure Concepts +@subsubsection Structure Concepts + +A structure object consists of a handle, structure data, and a vtable. +The handle is a Scheme value which points to both the vtable and the +structure's data. Structure data is a dynamically allocated region of +memory, private to the structure, divided up into typed fields. A +vtable is another structure used to hold type-specific data. Multiple +structures can share a common vtable. + +Three concepts are key to understanding structures. + +@itemize @bullet{} +@item @dfn{layout specifications} + +Layout specifications determine how memory allocated to structures is +divided up into fields. Programmers must write a layout specification +whenever a new type of structure is defined. + +@item @dfn{structural accessors} + +Structure access is by field number. There is only one set of +accessors common to all structure objects. + +@item @dfn{vtables} + +Vtables, themselves structures, are first class representations of +disjoint sub-types of structures in general. In most cases, when a +new structure is created, programmers must specify a vtable for the +new structure. Each vtable has a field describing the layout of its +instances. Vtables can have additional, user-defined fields as well. +@end itemize + + + +@node Structure Layout +@subsubsection Structure Layout + +When a structure is created, a region of memory is allocated to hold its +state. The @dfn{layout} of the structure's type determines how that +memory is divided into fields. + +Each field has a specified type. There are only three types allowed, each +corresponding to a one letter code. The allowed types are: + +@itemize @bullet{} +@item 'u' -- unprotected + +The field holds binary data that is not GC protected. + +@item 'p' -- protected + +The field holds a Scheme value and is GC protected. + +@item 's' -- self + +The field holds a Scheme value and is GC protected. When a structure is +created with this type of field, the field is initialized to refer to +the structure's own handle. This kind of field is mainly useful when +mixing Scheme and C code in which the C code may need to compute a +structure's handle given only the address of its malloc'd data. +@end itemize + + +Each field also has an associated access protection. There are only +three kinds of protection, each corresponding to a one letter code. +The allowed protections are: + +@itemize @bullet{} +@item 'w' -- writable + +The field can be read and written. + +@item 'r' -- readable + +The field can be read, but not written. + +@item 'o' -- opaque + +The field can be neither read nor written. This kind +of protection is for fields useful only to built-in routines. +@end itemize + +A layout specification is described by stringing together pairs +of letters: one to specify a field type and one to specify a field +protection. For example, a traditional cons pair type object could +be described as: + +@example +; cons pairs have two writable fields of Scheme data +"pwpw" +@end example + +A pair object in which the first field is held constant could be: + +@example +"prpw" +@end example + +Binary fields, (fields of type "u"), hold one @dfn{word} each. The +size of a word is a machine dependent value defined to be equal to the +value of the C expression: @code{sizeof (long)}. + +The last field of a structure layout may specify a tail array. +A tail array is indicated by capitalizing the field's protection +code ('W', 'R' or 'O'). A tail-array field is replaced by +a read-only binary data field containing an array size. The array +size is determined at the time the structure is created. It is followed +by a corresponding number of fields of the type specified for the +tail array. For example, a conventional Scheme vector can be +described as: + +@example +; A vector is an arbitrary number of writable fields holding Scheme +; values: +"pW" +@end example + +In the above example, field 0 contains the size of the vector and +fields beginning at 1 contain the vector elements. + +A kind of tagged vector (a constant tag followed by conventional +vector elements) might be: + +@example +"prpW" +@end example + + +Structure layouts are represented by specially interned symbols whose +name is a string of type and protection codes. To create a new +structure layout, use this procedure: + +@deffn {Scheme Procedure} make-struct-layout fields +@deffnx {C Function} scm_make_struct_layout (fields) +Return a new structure layout object. + +@var{fields} must be a string made up of pairs of characters +strung together. The first character of each pair describes a field +type, the second a field protection. Allowed types are 'p' for +GC-protected Scheme data, 'u' for unprotected binary data, and 's' for +a field that points to the structure itself. Allowed protections +are 'w' for mutable fields, 'r' for read-only fields, and 'o' for opaque +fields. The last field protection specification may be capitalized to +indicate that the field is a tail-array. +@end deffn + + + +@node Structure Basics +@subsubsection Structure Basics + +This section describes the basic procedures for creating and accessing +structures. + +@deffn {Scheme Procedure} make-struct vtable tail_array_size . init +@deffnx {C Function} scm_make_struct (vtable, tail_array_size, init) +Create a new structure. + +@var{type} must be a vtable structure (@pxref{Vtables}). + +@var{tail-elts} must be a non-negative integer. If the layout +specification indicated by @var{type} includes a tail-array, +this is the number of elements allocated to that array. + +The @var{init1}, @dots{} are optional arguments describing how +successive fields of the structure should be initialized. Only fields +with protection 'r' or 'w' can be initialized, except for fields of +type 's', which are automatically initialized to point to the new +structure itself; fields with protection 'o' can not be initialized by +Scheme programs. + +If fewer optional arguments than initializable fields are supplied, +fields of type 'p' get default value #f while fields of type 'u' are +initialized to 0. + +Structs are currently the basic representation for record-like data +structures in Guile. The plan is to eventually replace them with a +new representation which will at the same time be easier to use and +more powerful. + +For more information, see the documentation for @code{make-vtable-vtable}. +@end deffn + +@deffn {Scheme Procedure} struct? x +@deffnx {C Function} scm_struct_p (x) +Return @code{#t} iff @var{x} is a structure object, else +@code{#f}. +@end deffn + + +@deffn {Scheme Procedure} struct-ref handle pos +@deffnx {Scheme Procedure} struct-set! struct n value +@deffnx {C Function} scm_struct_ref (handle, pos) +@deffnx {C Function} scm_struct_set_x (struct, n, value) +Access (or modify) the @var{n}th field of @var{struct}. + +If the field is of type 'p', then it can be set to an arbitrary value. + +If the field is of type 'u', then it can only be set to a non-negative +integer value small enough to fit in one machine word. +@end deffn + + + +@node Vtables +@subsubsection Vtables + +Vtables are structures that are used to represent structure types. Each +vtable contains a layout specification in field +@code{vtable-index-layout} -- instances of the type are laid out +according to that specification. Vtables contain additional fields +which are used only internally to libguile. The variable +@code{vtable-offset-user} is bound to a field number. Vtable fields +at that position or greater are user definable. + +@deffn {Scheme Procedure} struct-vtable handle +@deffnx {C Function} scm_struct_vtable (handle) +Return the vtable structure that describes the type of @var{struct}. +@end deffn + +@deffn {Scheme Procedure} struct-vtable? x +@deffnx {C Function} scm_struct_vtable_p (x) +Return @code{#t} iff @var{x} is a vtable structure. +@end deffn + +If you have a vtable structure, @code{V}, you can create an instance of +the type it describes by using @code{(make-struct V ...)}. But where +does @code{V} itself come from? One possibility is that @code{V} is an +instance of a user-defined vtable type, @code{V'}, so that @code{V} is +created by using @code{(make-struct V' ...)}. Another possibility is +that @code{V} is an instance of the type it itself describes. Vtable +structures of the second sort are created by this procedure: + +@deffn {Scheme Procedure} make-vtable-vtable user_fields tail_array_size . init +@deffnx {C Function} scm_make_vtable_vtable (user_fields, tail_array_size, init) +Return a new, self-describing vtable structure. + +@var{user-fields} is a string describing user defined fields of the +vtable beginning at index @code{vtable-offset-user} +(see @code{make-struct-layout}). + +@var{tail-size} specifies the size of the tail-array (if any) of +this vtable. + +@var{init1}, @dots{} are the optional initializers for the fields of +the vtable. + +Vtables have one initializable system field---the struct printer. +This field comes before the user fields in the initializers passed +to @code{make-vtable-vtable} and @code{make-struct}, and thus works as +a third optional argument to @code{make-vtable-vtable} and a fourth to +@code{make-struct} when creating vtables: + +If the value is a procedure, it will be called instead of the standard +printer whenever a struct described by this vtable is printed. +The procedure will be called with arguments STRUCT and PORT. + +The structure of a struct is described by a vtable, so the vtable is +in essence the type of the struct. The vtable is itself a struct with +a vtable. This could go on forever if it weren't for the +vtable-vtables which are self-describing vtables, and thus terminate +the chain. + +There are several potential ways of using structs, but the standard +one is to use three kinds of structs, together building up a type +sub-system: one vtable-vtable working as the root and one or several +"types", each with a set of "instances". (The vtable-vtable should be +compared to the class <class> which is the class of itself.) + +@lisp +(define ball-root (make-vtable-vtable "pr" 0)) + +(define (make-ball-type ball-color) + (make-struct ball-root 0 + (make-struct-layout "pw") + (lambda (ball port) + (format port "#<a ~A ball owned by ~A>" + (color ball) + (owner ball))) + ball-color)) +(define (color ball) (struct-ref (struct-vtable ball) vtable-offset-user)) +(define (owner ball) (struct-ref ball 0)) + +(define red (make-ball-type 'red)) +(define green (make-ball-type 'green)) + +(define (make-ball type owner) (make-struct type 0 owner)) + +(define ball (make-ball green 'Nisse)) +ball @result{} #<a green ball owned by Nisse> +@end lisp +@end deffn + +@deffn {Scheme Procedure} struct-vtable-name vtable +@deffnx {C Function} scm_struct_vtable_name (vtable) +Return the name of the vtable @var{vtable}. +@end deffn + +@deffn {Scheme Procedure} set-struct-vtable-name! vtable name +@deffnx {C Function} scm_set_struct_vtable_name_x (vtable, name) +Set the name of the vtable @var{vtable} to @var{name}. +@end deffn + +@deffn {Scheme Procedure} struct-vtable-tag handle +@deffnx {C Function} scm_struct_vtable_tag (handle) +Return the vtable tag of the structure @var{handle}. +@end deffn + + +@node Arrays +@subsection Arrays +@tpindex Arrays + +@menu +* Conventional Arrays:: Arrays with arbitrary data. +* Array Mapping:: Applying a procedure to the contents of an array. +* Uniform Arrays:: Arrays with data of a single type. +* Bit Vectors:: Vectors of bits. +@end menu + +@node Conventional Arrays +@subsubsection Conventional Arrays + +@dfn{Conventional arrays} are a collection of cells organized into an +arbitrary number of dimensions. Each cell can hold any kind of Scheme +value and can be accessed in constant time by supplying an index for +each dimension. + +This contrasts with uniform arrays, which use memory more efficiently +but can hold data of only a single type. It contrasts also with lists +where inserting and deleting cells is more efficient, but more time is +usually required to access a particular cell. + +A conventional array is displayed as @code{#} followed by the @dfn{rank} +(number of dimensions) followed by the cells, organized into dimensions +using parentheses. The nesting depth of the parentheses is equal to +the rank. + +When an array is created, the range of each dimension must be +specified, e.g., to create a 2@cross{}3 array with a zero-based index: + +@example +(make-array 'ho 2 3) @result{} #2((ho ho ho) (ho ho ho)) +@end example + +The range of each dimension can also be given explicitly, e.g., another +way to create the same array: + +@example +(make-array 'ho '(0 1) '(0 2)) @result{} #2((ho ho ho) (ho ho ho)) +@end example + +A conventional array with one dimension based at zero is identical to +a vector: + +@example +(make-array 'ho 3) @result{} #(ho ho ho) +@end example + +The following procedures can be used with conventional arrays (or +vectors). An argument shown as @var{idx}@dots{} means one parameter +for each dimension in the array. Or a @var{idxlist} is a list of such +values, one for each dimension. + +@deffn {Scheme Procedure} array? obj [prot] +@deffnx {C Function} scm_array_p (obj, prot) +Return @code{#t} if the @var{obj} is an array, and @code{#f} if +not. + +The @var{prot} argument is used with uniform arrays (@pxref{Uniform +Arrays}). If given then the return is @code{#t} if @var{obj} is an +array and of that prototype. +@end deffn + +@deffn {Scheme Procedure} make-array initial-value bound @dots{} +Create and return an array that has as many dimensions as there are +@var{bound}s and fill it with @var{initial-value}. + +Each @var{bound} +may be a positive non-zero integer @var{N}, in which case the index for +that dimension can range from 0 through @var{N-1}; or an explicit index +range specifier in the form @code{(LOWER UPPER)}, where both @var{lower} +and @var{upper} are integers, possibly less than zero, and possibly the +same number (however, @var{lower} cannot be greater than @var{upper}). +See examples above. +@end deffn + +@c array-ref's type is `compiled-closure'. There's some weird stuff +@c going on in array.c, too. Let's call it a primitive. -twp + +@deffn {Scheme Procedure} array-ref array idx @dots{} +@deffnx {Scheme Procedure} uniform-vector-ref vec args +@deffnx {C Function} scm_uniform_vector_ref (vec, args) +Return the element at @code{(idx @dots{})} in @var{array}. + +@example +(define a (make-array 999 '(1 2) '(3 4))) +(array-ref a 2 4) @result{} 999 +@end example +@end deffn + +@deffn {Scheme Procedure} array-in-bounds? array idx @dots{} +@deffnx {C Function} scm_array_in_bounds_p (array, idxlist) +Return @code{#t} if the given index would be acceptable to +@code{array-ref}. + +@example +(define a (make-array #f '(1 2) '(3 4))) +(array-in-bounds? a 2 3) @result{} #f +(array-in-bounds? a 0 0) @result{} #f +@end example +@end deffn + +@c fixme: why do these sigs differ? -ttn 2001/07/19 01:14:12 +@deffn {Scheme Procedure} array-set! array obj idx @dots{} +@deffnx {Scheme Procedure} uniform-array-set1! array obj idxlist +@deffnx {C Function} scm_array_set_x (array, obj, idxlist) +Set the element at @code{(idx @dots{})} in @var{array} to @var{obj}. +The return value is unspecified. + +@example +(define a (make-array #f '(0 1) '(0 1))) +(array-set! a #t 1 1) +a @result{} #2((#f #f) (#f #t)) +@end example +@end deffn + +@deffn {Scheme Procedure} make-shared-array oldarray mapfunc bound @dots{} +@deffnx {C Function} scm_make_shared_array (oldarray, mapfunc, boundlist) +@code{make-shared-array} can be used to create shared subarrays of other +arrays. The @var{mapper} is a function that translates coordinates in +the new array into coordinates in the old array. A @var{mapper} must be +linear, and its range must stay within the bounds of the old array, but +it can be otherwise arbitrary. A simple example: + +@lisp +(define fred (make-array #f 8 8)) +(define freds-diagonal + (make-shared-array fred (lambda (i) (list i i)) 8)) +(array-set! freds-diagonal 'foo 3) +(array-ref fred 3 3) @result{} foo +(define freds-center + (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2)) +(array-ref freds-center 0 0) @result{} foo +@end lisp +@end deffn + +@deffn {Scheme Procedure} shared-array-increments array +@deffnx {C Function} scm_shared_array_increments (array) +For each dimension, return the distance between elements in the root vector. +@end deffn + +@deffn {Scheme Procedure} shared-array-offset array +@deffnx {C Function} scm_shared_array_offset (array) +Return the root vector index of the first element in the array. +@end deffn + +@deffn {Scheme Procedure} shared-array-root array +@deffnx {C Function} scm_shared_array_root (array) +Return the root vector of a shared array. +@end deffn + +@deffn {Scheme Procedure} transpose-array array dim1 @dots{} +@deffnx {C Function} scm_transpose_array (array, dimlist) +Return an array sharing contents with @var{array}, but with +dimensions arranged in a different order. There must be one +@var{dim} argument for each dimension of @var{array}. +@var{dim1}, @var{dim2}, @dots{} should be integers between 0 +and the rank of the array to be returned. Each integer in that +range must appear at least once in the argument list. + +The values of @var{dim1}, @var{dim2}, @dots{} correspond to +dimensions in the array to be returned, and their positions in the +argument list to dimensions of @var{array}. Several @var{dim}s +may have the same value, in which case the returned array will +have smaller rank than @var{array}. + +@lisp +(transpose-array '#2((a b) (c d)) 1 0) @result{} #2((a c) (b d)) +(transpose-array '#2((a b) (c d)) 0 0) @result{} #1(a d) +(transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) @result{} + #2((a 4) (b 5) (c 6)) +@end lisp +@end deffn + +@deffn {Scheme Procedure} enclose-array array dim1 @dots{} +@deffnx {C Function} scm_enclose_array (array, dimlist) +@var{dim1}, @var{dim2} @dots{} should be nonnegative integers less than +the rank of @var{array}. @code{enclose-array} returns an array +resembling an array of shared arrays. The dimensions of each shared +array are the same as the @var{dim}th dimensions of the original array, +the dimensions of the outer array are the same as those of the original +array that did not match a @var{dim}. + +An enclosed array is not a general Scheme array. Its elements may not +be set using @code{array-set!}. Two references to the same element of +an enclosed array will be @code{equal?} but will not in general be +@code{eq?}. The value returned by @code{array-prototype} when given an +enclosed array is unspecified. + +For example, + +@lisp +(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) +@result{} +#<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))> + +(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) +@result{} +#<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))> +@end lisp +@end deffn + +@deffn {Scheme Procedure} array-shape array +@deffnx {Scheme Procedure} array-dimensions array +@deffnx {C Function} scm_array_dimensions (array) +Return a list of the bounds for each dimenson of @var{array}. + +@code{array-shape} gives @code{(@var{lower} @var{upper})} for each +dimension. @code{array-dimensions} instead returns just +@math{@var{upper}+1} for dimensions with a 0 lower bound. Both are +suitable as input to @code{make-array}. + +For example, + +@example +(define a (make-array 'foo '(-1 3) 5)) +(array-shape a) @result{} ((-1 3) (0 4)) +(array-dimensions a) @result{} ((-1 3) 5) +@end example +@end deffn + +@deffn {Scheme Procedure} array-rank obj +@deffnx {C Function} scm_array_rank (obj) +Return the number of dimensions of an array @var{obj}, or if @var{obj} +is not an array then return 0. +@end deffn + +@deffn {Scheme Procedure} array->list array +@deffnx {C Function} scm_array_to_list (array) +Return a list consisting of all the elements, in order, of +@var{array}. +@end deffn + +@c FIXME: Describe how the order affects the copying (it matters for +@c shared arrays with the same underlying root vector, presumably). +@c +@deffn {Scheme Procedure} array-copy! src dst +@deffnx {Scheme Procedure} array-copy-in-order! src dst +@deffnx {C Function} scm_array_copy_x (src, dst) +Copy every element from vector or array @var{src} to the corresponding +element of @var{dst}. @var{dst} must have the same rank as @var{src}, +and be at least as large in each dimension. The return value is +unspecified. +@end deffn + +@deffn {Scheme Procedure} array-fill! array fill +@deffnx {C Function} scm_array_fill_x (array, fill) +Store @var{fill} in every element of @var{array}. The value returned +is unspecified. +@end deffn + +@c begin (texi-doc-string "guile" "array-equal?") +@deffn {Scheme Procedure} array-equal? array1 array2 @dots{} +Return @code{#t} if all arguments are arrays with the same shape, the +same type, and have corresponding elements which are either +@code{equal?} or @code{array-equal?}. This function differs from +@code{equal?} in that a one dimensional shared array may be +@var{array-equal?} but not @var{equal?} to a vector or uniform vector. +@end deffn + +@deffn {Scheme Procedure} array-contents array [strict] +@deffnx {C Function} scm_array_contents (array, strict) +If @var{array} may be @dfn{unrolled} into a one dimensional shared array +without changing their order (last subscript changing fastest), then +@code{array-contents} returns that shared array, otherwise it returns +@code{#f}. All arrays made by @code{make-array} and +@code{make-uniform-array} may be unrolled, some arrays made by +@code{make-shared-array} may not be. + +If the optional argument @var{strict} is provided, a shared array will +be returned only if its elements are stored internally contiguous in +memory. +@end deffn + +@node Array Mapping +@subsubsection Array Mapping + +@c FIXME: array-map! accepts no source arrays at all, and in that +@c case makes calls "(proc)". Is that meant to be a documented +@c feature? +@c +@c FIXME: array-for-each doesn't say what happens if the sources have +@c different index ranges. The code currently iterates over the +@c indices of the first and expects the others to cover those. That +@c at least vaguely matches array-map!, but is is meant to be a +@c documented feature? + +@deffn {Scheme Procedure} array-map! dst proc src1 @dots{} srcN +@deffnx {Scheme Procedure} array-map-in-order! dst proc src1 @dots{} srcN +@deffnx {C Function} scm_array_map_x (dst, proc, srclist) +Set each element of the @var{dst} array to values obtained from calls +to @var{proc}. The value returned is unspecified. + +Each call is @code{(@var{proc} @var{elem1} @dots{} @var{elemN})}, +where each @var{elem} is from the corresponding @var{src} array, at +the @var{dst} index. @code{array-map-in-order!} makes the calls in +row-major order, @code{array-map!} makes them in an unspecified order. + +The @var{src} arrays must have the same number of dimensions as +@var{dst}, and must have a range for each dimension which covers the +range in @var{dst}. This ensures all @var{dst} indices are valid in +each @var{src}. +@end deffn + +@deffn {Scheme Procedure} array-for-each proc src1 @dots{} srcN +@deffnx {C Function} scm_array_for_each (proc, src1, srclist) +Apply @var{proc} to each tuple of elements of @var{src1} @dots{} +@var{srcN}, in row-major order. The value returned is unspecified. +@end deffn + +@deffn {Scheme Procedure} array-index-map! dst proc +@deffnx {C Function} scm_array_index_map_x (dst, proc) +Set each element of the @var{dst} array to values returned by calls to +@var{proc}. The value returned is unspecified. + +Each call is @code{(@var{proc} @var{i1} @dots{} @var{iN})}, where +@var{i1}@dots{}@var{iN} is the destination index, one parameter for +each dimension. The order in which the calls are made is unspecified. + +For example, to create a @m{4\times4, 4x4} matrix representing a +cyclic group, + +@tex +\advance\leftskip by 2\lispnarrowing { +$\left(\matrix{% +0 & 1 & 2 & 3 \cr +1 & 2 & 3 & 0 \cr +2 & 3 & 0 & 1 \cr +3 & 0 & 1 & 2 \cr +}\right)$} \par +@end tex +@ifnottex +@example + / 0 1 2 3 \ + | 1 2 3 0 | + | 2 3 0 1 | + \ 3 0 1 2 / +@end example +@end ifnottex + +@example +(define a (make-array #f 4 4)) +(array-index-map! a (lambda (i j) + (modulo (+ i j) 4))) +@end example +@end deffn + +@node Uniform Arrays +@subsubsection Uniform Arrays +@tpindex Uniform Arrays + +@noindent +@dfn{Uniform arrays} have elements all of the +same type and occupy less storage than conventional +arrays. Uniform arrays with a single zero-based dimension +are also known as @dfn{uniform vectors}. The procedures in +this section can also be used on conventional arrays, vectors, +bit-vectors and strings. + +@noindent +When creating a uniform array, the type of data to be stored +is indicated with a @var{prototype} argument. The following table +lists the types available and example prototypes: + +@example +prototype type printing character + +#t boolean (bit-vector) b +#\a char (string) a +#\nul byte (integer) y +'s short (integer) h +1 unsigned long (integer) u +-1 signed long (integer) e +'l signed long long (integer) l +1.0 float (single precision) s +1/3 double (double precision float) i +0+i complex (double precision) c +() conventional vector +@end example + +Note that with the introduction of exact fractions in Guile 1.8, +@samp{1/3} here is now a fraction, where previously such an expression +was a double @samp{0.333@dots{}}. For most normal usages this should +be source code compatible. + +Unshared uniform arrays of characters with a single zero-based dimension +are identical to strings: + +@example +(make-uniform-array #\a 3) @result{} +"aaa" +@end example + +@noindent +Unshared uniform arrays of booleans with a single zero-based dimension +are identical to @ref{Bit Vectors, bit-vectors}. + +@example +(make-uniform-array #t 3) @result{} +#*111 +@end example + +@noindent +Other uniform vectors are written in a form similar to that of vectors, +except that a single character from the above table is put between +@code{#} and @code{(}. For example, a uniform vector of signed +long integers is displayed in the form @code{'#e(3 5 9)}. + +@deffn {Scheme Procedure} make-uniform-array prototype bound1 bound2 @dots{} +Create and return a uniform array of type corresponding to +@var{prototype} that has as many dimensions as there are @var{bound}s +and fill it with @var{prototype}. +@end deffn + +@deffn {Scheme Procedure} array-prototype ra +@deffnx {C Function} scm_array_prototype (ra) +Return an object that would produce an array of the same type +as @var{array}, if used as the @var{prototype} for +@code{make-uniform-array}. +@end deffn + +@deffn {Scheme Procedure} list->uniform-array ndim prot lst +@deffnx {Scheme Procedure} list->uniform-vector prot lst +@deffnx {C Function} scm_list_to_uniform_array (ndim, prot, lst) +Return a uniform array of the type indicated by prototype +@var{prot} with elements the same as those of @var{lst}. +Elements must be of the appropriate type, no coercions are +done. +@end deffn + +@deffn {Scheme Procedure} uniform-vector-fill! uve fill +Store @var{fill} in every element of @var{uve}. The value returned is +unspecified. +@end deffn + +@deffn {Scheme Procedure} uniform-vector-length v +@deffnx {C Function} scm_uniform_vector_length (v) +Return the number of elements in @var{uve}. +@end deffn + +@deffn {Scheme Procedure} dimensions->uniform-array dims prot [fill] +@deffnx {Scheme Procedure} make-uniform-vector length prototype [fill] +@deffnx {C Function} scm_dimensions_to_uniform_array (dims, prot, fill) +Create and return a uniform array or vector of type +corresponding to @var{prototype} with dimensions @var{dims} or +length @var{length}. If @var{fill} is supplied, it's used to +fill the array, otherwise @var{prototype} is used. +@end deffn + +@c Another compiled-closure. -twp + +@deffn {Scheme Procedure} uniform-array-read! ra [port_or_fd [start [end]]] +@deffnx {Scheme Procedure} uniform-vector-read! uve [port-or-fdes] [start] [end] +@deffnx {C Function} scm_uniform_array_read_x (ra, port_or_fd, start, end) +Attempt to read all elements of @var{ura}, in lexicographic order, as +binary objects from @var{port-or-fdes}. +If an end of file is encountered, +the objects up to that point are put into @var{ura} +(starting at the beginning) and the remainder of the array is +unchanged. + +The optional arguments @var{start} and @var{end} allow +a specified region of a vector (or linearized array) to be read, +leaving the remainder of the vector unchanged. + +@code{uniform-array-read!} returns the number of objects read. +@var{port-or-fdes} may be omitted, in which case it defaults to the value +returned by @code{(current-input-port)}. +@end deffn + +@deffn {Scheme Procedure} uniform-array-write v [port_or_fd [start [end]]] +@deffnx {Scheme Procedure} uniform-vector-write uve [port-or-fdes] [start] [end] +@deffnx {C Function} scm_uniform_array_write (v, port_or_fd, start, end) +Writes all elements of @var{ura} as binary objects to +@var{port-or-fdes}. + +The optional arguments @var{start} +and @var{end} allow +a specified region of a vector (or linearized array) to be written. + +The number of objects actually written is returned. +@var{port-or-fdes} may be +omitted, in which case it defaults to the value returned by +@code{(current-output-port)}. +@end deffn + +@node Bit Vectors +@subsubsection Bit Vectors + +@noindent +Bit vectors are a specific type of uniform array: an array of booleans +with a single zero-based index. + +@noindent +They are displayed as a sequence of @code{0}s and +@code{1}s prefixed by @code{#*}, e.g., + +@example +(make-uniform-vector 8 #t #f) @result{} +#*00000000 +@end example + +@deffn {Scheme Procedure} bit-count bool bitvector +@deffnx {C Function} scm_bit_count (bool, bitvector) +Return a count of how many entries in @var{bitvector} are equal to +@var{bool}. For example, + +@example +(bit-count #f #*000111000) @result{} 6 +@end example +@end deffn + +@deffn {Scheme Procedure} bit-position bool bitvector start +@deffnx {C Function} scm_bit_position (bool, bitvector, start) +Return the index of the first occurrance of @var{bool} in +@var{bitvector}, starting from @var{start}. If there is no @var{bool} +entry between @var{start} and the end of @var{bitvector}, then return +@code{#f}. For example, + +@example +(bit-position #t #*000101 0) @result{} 3 +(bit-position #f #*0001111 3) @result{} #f +@end example +@end deffn + +@deffn {Scheme Procedure} bit-invert! bitvector +@deffnx {C Function} scm_bit_invert_x (bitvector) +Modify @var{bitvector} by replacing each element with its negation. +@end deffn + +@deffn {Scheme Procedure} bit-set*! bitvector uvec bool +@deffnx {C Function} scm_bit_set_star_x (bitvector, uvec, bool) +Set entries of @var{bitvector} to @var{bool}, with @var{uvec} +selecting the entries to change. The return value is unspecified. + +If @var{uvec} is a bit vector, then those entries where it has +@code{#t} are the ones in @var{bitvector} which are set to @var{bool}. +@var{uvec} and @var{bitvector} must be the same length. When +@var{bool} is @code{#t} it's like @var{uvec} is OR'ed into +@var{bitvector}. Or when @var{bool} is @code{#f} it can be seen as an +ANDNOT. + +@example +(define bv #*01000010) +(bit-set*! bv #*10010001 #t) +bv +@result{} #*11010011 +@end example + +If @var{uvec} is a uniform vector of unsigned long integers, then +they're indexes into @var{bitvector} which are set to @var{bool}. + +@example +(define bv #*01000010) +(bit-set*! bv #u(5 2 7) #t) +bv +@result{} #*01100111 +@end example +@end deffn + +@deffn {Scheme Procedure} bit-count* bitvector uvec bool +@deffnx {C Function} scm_bit_count_star (bitvector, uvec, bool) +Return a count of how many entries in @var{bitvector} are equal to +@var{bool}, with @var{uvec} selecting the entries to consider. + +@var{uvec} is interpreted in the same way as for @code{bit-set*!} +above. Namely, if @var{uvec} is a bit vector then entries which have +@code{#t} there are considered in @var{bitvector}. Or if @var{uvec} +is a uniform vector of unsigned long integers then it's the indexes in +@var{bitvector} to consider. + +For example, + +@example +(bit-count* #*01110111 #*11001101 #t) @result{} 3 +(bit-count* #*01110111 #u(7 0 4) #f) @result{} 2 +@end example +@end deffn + + +@node Dictionary Types +@subsection Dictionary Types + +A @dfn{dictionary} object is a data structure used to index +information in a user-defined way. In standard Scheme, the main +aggregate data types are lists and vectors. Lists are not really +indexed at all, and vectors are indexed only by number +(e.g. @code{(vector-ref foo 5)}). Often you will find it useful +to index your data on some other type; for example, in a library +catalog you might want to look up a book by the name of its +author. Dictionaries are used to help you organize information in +such a way. + +An @dfn{association list} (or @dfn{alist} for short) is a list of +key-value pairs. Each pair represents a single quantity or +object; the @code{car} of the pair is a key which is used to +identify the object, and the @code{cdr} is the object's value. + +A @dfn{hash table} also permits you to index objects with +arbitrary keys, but in a way that makes looking up any one object +extremely fast. A well-designed hash system makes hash table +lookups almost as fast as conventional array or vector references. + +Alists are popular among Lisp programmers because they use only +the language's primitive operations (lists, @dfn{car}, @dfn{cdr} +and the equality primitives). No changes to the language core are +necessary. Therefore, with Scheme's built-in list manipulation +facilities, it is very convenient to handle data stored in an +association list. Also, alists are highly portable and can be +easily implemented on even the most minimal Lisp systems. + +However, alists are inefficient, especially for storing large +quantities of data. Because we want Guile to be useful for large +software systems as well as small ones, Guile provides a rich set +of tools for using either association lists or hash tables. + +@node Association Lists +@subsection Association Lists +@tpindex Association Lists +@tpindex Alist + +@cindex Association List +@cindex Alist +@cindex Database + +An association list is a conventional data structure that is often used +to implement simple key-value databases. It consists of a list of +entries in which each entry is a pair. The @dfn{key} of each entry is +the @code{car} of the pair and the @dfn{value} of each entry is the +@code{cdr}. + +@example +ASSOCIATION LIST ::= '( (KEY1 . VALUE1) + (KEY2 . VALUE2) + (KEY3 . VALUE3) + @dots{} + ) +@end example + +@noindent +Association lists are also known, for short, as @dfn{alists}. + +The structure of an association list is just one example of the infinite +number of possible structures that can be built using pairs and lists. +As such, the keys and values in an association list can be manipulated +using the general list structure procedures @code{cons}, @code{car}, +@code{cdr}, @code{set-car!}, @code{set-cdr!} and so on. However, +because association lists are so useful, Guile also provides specific +procedures for manipulating them. + +@menu +* Alist Key Equality:: +* Adding or Setting Alist Entries:: +* Retrieving Alist Entries:: +* Removing Alist Entries:: +* Sloppy Alist Functions:: +* Alist Example:: +@end menu + +@node Alist Key Equality +@subsubsection Alist Key Equality + +All of Guile's dedicated association list procedures, apart from +@code{acons}, come in three flavours, depending on the level of equality +that is required to decide whether an existing key in the association +list is the same as the key that the procedure call uses to identify the +required entry. + +@itemize @bullet +@item +Procedures with @dfn{assq} in their name use @code{eq?} to determine key +equality. + +@item +Procedures with @dfn{assv} in their name use @code{eqv?} to determine +key equality. + +@item +Procedures with @dfn{assoc} in their name use @code{equal?} to +determine key equality. +@end itemize + +@code{acons} is an exception because it is used to build association +lists which do not require their entries' keys to be unique. + +@node Adding or Setting Alist Entries +@subsubsection Adding or Setting Alist Entries + +@code{acons} adds a new entry to an association list and returns the +combined association list. The combined alist is formed by consing the +new entry onto the head of the alist specified in the @code{acons} +procedure call. So the specified alist is not modified, but its +contents become shared with the tail of the combined alist that +@code{acons} returns. + +In the most common usage of @code{acons}, a variable holding the +original association list is updated with the combined alist: + +@example +(set! address-list (acons name address address-list)) +@end example + +In such cases, it doesn't matter that the old and new values of +@code{address-list} share some of their contents, since the old value is +usually no longer independently accessible. + +Note that @code{acons} adds the specified new entry regardless of +whether the alist may already contain entries with keys that are, in +some sense, the same as that of the new entry. Thus @code{acons} is +ideal for building alists where there is no concept of key uniqueness. + +@example +(set! task-list (acons 3 "pay gas bill" '())) +task-list +@result{} +((3 . "pay gas bill")) + +(set! task-list (acons 3 "tidy bedroom" task-list)) +task-list +@result{} +((3 . "tidy bedroom") (3 . "pay gas bill")) +@end example + +@code{assq-set!}, @code{assv-set!} and @code{assoc-set!} are used to add +or replace an entry in an association list where there @emph{is} a +concept of key uniqueness. If the specified association list already +contains an entry whose key is the same as that specified in the +procedure call, the existing entry is replaced by the new one. +Otherwise, the new entry is consed onto the head of the old association +list to create the combined alist. In all cases, these procedures +return the combined alist. + +@code{assq-set!} and friends @emph{may} destructively modify the +structure of the old association list in such a way that an existing +variable is correctly updated without having to @code{set!} it to the +value returned: + +@example +address-list +@result{} +(("mary" . "34 Elm Road") ("james" . "16 Bow Street")) + +(assoc-set! address-list "james" "1a London Road") +@result{} +(("mary" . "34 Elm Road") ("james" . "1a London Road")) + +address-list +@result{} +(("mary" . "34 Elm Road") ("james" . "1a London Road")) +@end example + +Or they may not: + +@example +(assoc-set! address-list "bob" "11 Newington Avenue") +@result{} +(("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road") + ("james" . "1a London Road")) + +address-list +@result{} +(("mary" . "34 Elm Road") ("james" . "1a London Road")) +@end example + +The only safe way to update an association list variable when adding or +replacing an entry like this is to @code{set!} the variable to the +returned value: + +@example +(set! address-list + (assoc-set! address-list "bob" "11 Newington Avenue")) +address-list +@result{} +(("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road") + ("james" . "1a London Road")) +@end example + +Because of this slight inconvenience, you may find it more convenient to +use hash tables to store dictionary data. If your application will not +be modifying the contents of an alist very often, this may not make much +difference to you. + +If you need to keep the old value of an association list in a form +independent from the list that results from modification by +@code{acons}, @code{assq-set!}, @code{assv-set!} or @code{assoc-set!}, +use @code{list-copy} to copy the old association list before modifying +it. + +@deffn {Scheme Procedure} acons key value alist +@deffnx {C Function} scm_acons (key, value, alist) +Add a new key-value pair to @var{alist}. A new pair is +created whose car is @var{key} and whose cdr is @var{value}, and the +pair is consed onto @var{alist}, and the new list is returned. This +function is @emph{not} destructive; @var{alist} is not modified. +@end deffn + +@deffn {Scheme Procedure} assq-set! alist key val +@deffnx {Scheme Procedure} assv-set! alist key value +@deffnx {Scheme Procedure} assoc-set! alist key value +@deffnx {C Function} scm_assq_set_x (alist, key, val) +@deffnx {C Function} scm_assv_set_x (alist, key, val) +@deffnx {C Function} scm_assoc_set_x (alist, key, val) +Reassociate @var{key} in @var{alist} with @var{value}: find any existing +@var{alist} entry for @var{key} and associate it with the new +@var{value}. If @var{alist} does not contain an entry for @var{key}, +add a new one. Return the (possibly new) alist. + +These functions do not attempt to verify the structure of @var{alist}, +and so may cause unusual results if passed an object that is not an +association list. +@end deffn + +@node Retrieving Alist Entries +@subsubsection Retrieving Alist Entries +@rnindex assq +@rnindex assv +@rnindex assoc + +@code{assq}, @code{assv} and @code{assoc} take an alist and a key as +arguments and return the entry for that key if an entry exists, or +@code{#f} if there is no entry for that key. Note that, in the cases +where an entry exists, these procedures return the complete entry, that +is @code{(KEY . VALUE)}, not just the value. + +@deffn {Scheme Procedure} assq key alist +@deffnx {Scheme Procedure} assv key alist +@deffnx {Scheme Procedure} assoc key alist +@deffnx {C Function} scm_assq (key, alist) +@deffnx {C Function} scm_assv (key, alist) +@deffnx {C Function} scm_assoc (key, alist) +Fetch the entry in @var{alist} that is associated with @var{key}. To +decide whether the argument @var{key} matches a particular entry in +@var{alist}, @code{assq} compares keys with @code{eq?}, @code{assv} +uses @code{eqv?} and @code{assoc} uses @code{equal?}. If @var{key} +cannot be found in @var{alist} (according to whichever equality +predicate is in use), then return @code{#f}. These functions +return the entire alist entry found (i.e. both the key and the value). +@end deffn + +@code{assq-ref}, @code{assv-ref} and @code{assoc-ref}, on the other +hand, take an alist and a key and return @emph{just the value} for that +key, if an entry exists. If there is no entry for the specified key, +these procedures return @code{#f}. + +This creates an ambiguity: if the return value is @code{#f}, it means +either that there is no entry with the specified key, or that there +@emph{is} an entry for the specified key, with value @code{#f}. +Consequently, @code{assq-ref} and friends should only be used where it +is known that an entry exists, or where the ambiguity doesn't matter +for some other reason. + +@deffn {Scheme Procedure} assq-ref alist key +@deffnx {Scheme Procedure} assv-ref alist key +@deffnx {Scheme Procedure} assoc-ref alist key +@deffnx {C Function} scm_assq_ref (alist, key) +@deffnx {C Function} scm_assv_ref (alist, key) +@deffnx {C Function} scm_assoc_ref (alist, key) +Like @code{assq}, @code{assv} and @code{assoc}, except that only the +value associated with @var{key} in @var{alist} is returned. These +functions are equivalent to + +@lisp +(let ((ent (@var{associator} @var{key} @var{alist}))) + (and ent (cdr ent))) +@end lisp + +where @var{associator} is one of @code{assq}, @code{assv} or @code{assoc}. +@end deffn + +@node Removing Alist Entries +@subsubsection Removing Alist Entries + +To remove the element from an association list whose key matches a +specified key, use @code{assq-remove!}, @code{assv-remove!} or +@code{assoc-remove!} (depending, as usual, on the level of equality +required between the key that you specify and the keys in the +association list). + +As with @code{assq-set!} and friends, the specified alist may or may not +be modified destructively, and the only safe way to update a variable +containing the alist is to @code{set!} it to the value that +@code{assq-remove!} and friends return. + +@example +address-list +@result{} +(("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road") + ("james" . "1a London Road")) + +(set! address-list (assoc-remove! address-list "mary")) +address-list +@result{} +(("bob" . "11 Newington Avenue") ("james" . "1a London Road")) +@end example + +Note that, when @code{assq/v/oc-remove!} is used to modify an +association list that has been constructed only using the corresponding +@code{assq/v/oc-set!}, there can be at most one matching entry in the +alist, so the question of multiple entries being removed in one go does +not arise. If @code{assq/v/oc-remove!} is applied to an association +list that has been constructed using @code{acons}, or an +@code{assq/v/oc-set!} with a different level of equality, or any mixture +of these, it removes only the first matching entry from the alist, even +if the alist might contain further matching entries. For example: + +@example +(define address-list '()) +(set! address-list (assq-set! address-list "mary" "11 Elm Street")) +(set! address-list (assq-set! address-list "mary" "57 Pine Drive")) +address-list +@result{} +(("mary" . "57 Pine Drive") ("mary" . "11 Elm Street")) + +(set! address-list (assoc-remove! address-list "mary")) +address-list +@result{} +(("mary" . "11 Elm Street")) +@end example + +In this example, the two instances of the string "mary" are not the same +when compared using @code{eq?}, so the two @code{assq-set!} calls add +two distinct entries to @code{address-list}. When compared using +@code{equal?}, both "mary"s in @code{address-list} are the same as the +"mary" in the @code{assoc-remove!} call, but @code{assoc-remove!} stops +after removing the first matching entry that it finds, and so one of the +"mary" entries is left in place. + +@deffn {Scheme Procedure} assq-remove! alist key +@deffnx {Scheme Procedure} assv-remove! alist key +@deffnx {Scheme Procedure} assoc-remove! alist key +@deffnx {C Function} scm_assq_remove_x (alist, key) +@deffnx {C Function} scm_assv_remove_x (alist, key) +@deffnx {C Function} scm_assoc_remove_x (alist, key) +Delete the first entry in @var{alist} associated with @var{key}, and return +the resulting alist. +@end deffn + +@node Sloppy Alist Functions +@subsubsection Sloppy Alist Functions + +@code{sloppy-assq}, @code{sloppy-assv} and @code{sloppy-assoc} behave +like the corresponding non-@code{sloppy-} procedures, except that they +return @code{#f} when the specified association list is not well-formed, +where the non-@code{sloppy-} versions would signal an error. + +Specifically, there are two conditions for which the non-@code{sloppy-} +procedures signal an error, which the @code{sloppy-} procedures handle +instead by returning @code{#f}. Firstly, if the specified alist as a +whole is not a proper list: + +@example +(assoc "mary" '((1 . 2) ("key" . "door") . "open sesame")) +@result{} +ERROR: In procedure assoc in expression (assoc "mary" (quote #)): +ERROR: Wrong type argument in position 2 (expecting association list): ((1 . 2) ("key" . "door") . "open sesame") + +(sloppy-assoc "mary" '((1 . 2) ("key" . "door") . "open sesame")) +@result{} +#f +@end example + +@noindent +Secondly, if one of the entries in the specified alist is not a pair: + +@example +(assoc 2 '((1 . 1) 2 (3 . 9))) +@result{} +ERROR: In procedure assoc in expression (assoc 2 (quote #)): +ERROR: Wrong type argument in position 2 (expecting association list): ((1 . 1) 2 (3 . 9)) + +(sloppy-assoc 2 '((1 . 1) 2 (3 . 9))) +@result{} +#f +@end example + +Unless you are explicitly working with badly formed association lists, +it is much safer to use the non-@code{sloppy-} procedures, because they +help to highlight coding and data errors that the @code{sloppy-} +versions would silently cover up. + +@deffn {Scheme Procedure} sloppy-assq key alist +@deffnx {C Function} scm_sloppy_assq (key, alist) +Behaves like @code{assq} but does not do any error checking. +Recommended only for use in Guile internals. +@end deffn + +@deffn {Scheme Procedure} sloppy-assv key alist +@deffnx {C Function} scm_sloppy_assv (key, alist) +Behaves like @code{assv} but does not do any error checking. +Recommended only for use in Guile internals. +@end deffn + +@deffn {Scheme Procedure} sloppy-assoc key alist +@deffnx {C Function} scm_sloppy_assoc (key, alist) +Behaves like @code{assoc} but does not do any error checking. +Recommended only for use in Guile internals. +@end deffn + +@node Alist Example +@subsubsection Alist Example + +Here is a longer example of how alists may be used in practice. + +@lisp +(define capitals '(("New York" . "Albany") + ("Oregon" . "Salem") + ("Florida" . "Miami"))) + +;; What's the capital of Oregon? +(assoc "Oregon" capitals) @result{} ("Oregon" . "Salem") +(assoc-ref capitals "Oregon") @result{} "Salem" + +;; We left out South Dakota. +(set! capitals + (assoc-set! capitals "South Dakota" "Pierre")) +capitals +@result{} (("South Dakota" . "Pierre") + ("New York" . "Albany") + ("Oregon" . "Salem") + ("Florida" . "Miami")) + +;; And we got Florida wrong. +(set! capitals + (assoc-set! capitals "Florida" "Tallahassee")) +capitals +@result{} (("South Dakota" . "Pierre") + ("New York" . "Albany") + ("Oregon" . "Salem") + ("Florida" . "Tallahassee")) + +;; After Oregon secedes, we can remove it. +(set! capitals + (assoc-remove! capitals "Oregon")) +capitals +@result{} (("South Dakota" . "Pierre") + ("New York" . "Albany") + ("Florida" . "Tallahassee")) +@end lisp + +@node Hash Tables +@subsection Hash Tables +@tpindex Hash Tables + +@c FIXME::martin: Review me! + +Hash tables are dictionaries which offer similar functionality as +association lists: They provide a mapping from keys to values. The +difference is that association lists need time linear in the size of +elements when searching for entries, whereas hash tables can normally +search in constant time. The drawback is that hash tables require a +little bit more memory, and that you can not use the normal list +procedures (@pxref{Lists}) for working with them. + +@menu +* Hash Table Examples:: Demonstration of hash table usage. +* Hash Table Reference:: Hash table procedure descriptions. +@end menu + + +@node Hash Table Examples +@subsubsection Hash Table Examples + +@c FIXME::martin: Review me! + +For demonstration purposes, this section gives a few usage examples of +some hash table procedures, together with some explanation what they do. + +First we start by creating a new hash table with 31 slots, and +populate it with two key/value pairs. + +@lisp +(define h (make-hash-table 31)) + +(hashq-create-handle! h 'foo "bar") +@result{} +(foo . "bar") + +(hashq-create-handle! h 'braz "zonk") +@result{} +(braz . "zonk") + +(hashq-create-handle! h 'frob #f) +@result{} +(frob . #f) +@end lisp + +You can get the value for a given key with the procedure +@code{hashq-ref}, but the problem with this procedure is that you +cannot reliably determine whether a key does exists in the table. The +reason is that the procedure returns @code{#f} if the key is not in +the table, but it will return the same value if the key is in the +table and just happens to have the value @code{#f}, as you can see in +the following examples. + +@lisp +(hashq-ref h 'foo) +@result{} +"bar" + +(hashq-ref h 'frob) +@result{} +#f + +(hashq-ref h 'not-there) +@result{} +#f +@end lisp + +Better is to use the procedure @code{hashq-get-handle}, which makes a +distinction between the two cases. Just like @code{assq}, this +procedure returns a key/value-pair on success, and @code{#f} if the +key is not found. + +@lisp +(hashq-get-handle h 'foo) +@result{} +(foo . "bar") + +(hashq-get-handle h 'not-there) +@result{} +#f +@end lisp + +There is no procedure for calculating the number of key/value-pairs in +a hash table, but @code{hash-fold} can be used for doing exactly that. + +@lisp +(hash-fold (lambda (key value seed) (+ 1 seed)) 0 h) +@result{} +3 +@end lisp + +@node Hash Table Reference +@subsubsection Hash Table Reference + +@c FIXME: Describe in broad terms what happens for resizing, and what +@c the initial size means for this. + +Like the association list functions, the hash table functions come in +several varieties, according to the equality test used for the keys. +Plain @code{hash-} functions use @code{equal?}, @code{hashq-} +functions use @code{eq?}, @code{hashv-} functions use @code{eqv?}, and +the @code{hashx-} functions use an application supplied test. + +A single @code{make-hash-table} creates a hash table suitable for use +with any set of functions, but it's imperative that just one set is +then used consistently, or results will be unpredictable. + +@sp 1 +Hash tables are implemented as a vector indexed by a hash value formed +from the key, with an association list of key/value pairs for each +bucket in case distinct keys hash together. Direct access to the +pairs in those lists is provided by the @code{-handle-} functions. + +When the number of table entries goes above a threshold the vector is +increased and the entries rehashed, to prevent the bucket lists +becoming too long and slowing down accesses. When the number of +entries goes below a threshold the vector is decreased to save space. + +@sp 1 +For the @code{hashx-} ``extended'' routines, an application supplies a +@var{hash} function producing an integer index like @code{hashq} etc +below, and an @var{assoc} alist search function like @code{assq} etc +(@pxref{Retrieving Alist Entries}). Here's an example of such +functions implementing case-insensitive hashing of string keys, + +@example +(use-modules (srfi srfi-1) + (srfi srfi-13)) + +(define (my-hash str size) + (remainder (string-hash-ci str) size)) +(define (my-assoc str alist) + (find (lambda (pair) (string-ci=? str (car pair))) alist)) + +(define my-table (make-hash-table)) +(hashx-set! my-hash my-assoc my-table "foo" 123) + +(hashx-ref my-hash my-assoc my-table "FOO") +@result{} 123 +@end example + +In a @code{hashx-} @var{hash} function the aim is to spread keys +across the vector, so bucket lists don't become long. But the actual +values are arbitrary as long as they're in the range 0 to +@math{@var{size}-1}. Helpful functions for forming a hash value, in +addition to @code{hashq} etc below, include @code{symbol-hash} +(@pxref{Symbol Keys}), @code{string-hash} and @code{string-hash-ci} +(@pxref{SRFI-13 Comparison}), and @code{char-set-hash} (@pxref{SRFI-14 +Predicates/Comparison}). + +Note that currently, unfortunately, there's no @code{hashx-remove!} +function, which rather limits the usefulness of the @code{hashx-} +routines. + +@sp 1 +@deffn {Scheme Procedure} make-hash-table [size] +Create a new hash table, with an optional minimum vector @var{size}. + +When @var{size} is given, the table vector will still grow and shrink +automatically, as described above, but with @var{size} as a minimum. +If an application knows roughly how many entries the table will hold +then it can use @var{size} to avoid rehashing when initial entries are +added. +@end deffn + +@deffn {Scheme Procedure} hash-ref table key [dflt] +@deffnx {Scheme Procedure} hashq-ref table key [dflt] +@deffnx {Scheme Procedure} hashv-ref table key [dflt] +@deffnx {Scheme Procedure} hashx-ref hash assoc table key [dflt] +@deffnx {C Function} scm_hash_ref (table, key, dflt) +@deffnx {C Function} scm_hashq_ref (table, key, dflt) +@deffnx {C Function} scm_hashv_ref (table, key, dflt) +@deffnx {C Function} scm_hashx_ref (hash, assoc, table, key, dflt) +Lookup @var{key} in the given hash @var{table}, and return the +associated value. If @var{key} is not found, return @var{dflt}, or +@code{#f} if @var{dflt} is not given. +@end deffn + +@deffn {Scheme Procedure} hash-set! table key val +@deffnx {Scheme Procedure} hashq-set! table key val +@deffnx {Scheme Procedure} hashv-set! table key val +@deffnx {Scheme Procedure} hashx-set! hash assoc table key val +@deffnx {C Function} scm_hash_set_x (table, key, val) +@deffnx {C Function} scm_hashq_set_x (table, key, val) +@deffnx {C Function} scm_hashv_set_x (table, key, val) +@deffnx {C Function} scm_hashx_set_x (hash, assoc, table, key, val) +Associate @var{val} with @var{key} in the given hash @var{table}. If +@var{key} is already present then it's associated value is changed. +If it's not present then a new entry is created. +@end deffn + +@deffn {Scheme Procedure} hash-remove! table key +@deffnx {Scheme Procedure} hashq-remove! table key +@deffnx {Scheme Procedure} hashv-remove! table key +@deffnx {C Function} scm_hash_remove_x (table, key) +@deffnx {C Function} scm_hashq_remove_x (table, key) +@deffnx {C Function} scm_hashv_remove_x (table, key) +Remove any association for @var{key} in the given hash @var{table}. +If @var{key} is not in @var{table} then nothing is done. +@end deffn + +@deffn {Scheme Procedure} hash key size +@deffnx {Scheme Procedure} hashq key size +@deffnx {Scheme Procedure} hashv key size +@deffnx {C Function} scm_hash (key, size) +@deffnx {C Function} scm_hashq (key, size) +@deffnx {C Function} scm_hashv (key, size) +Return a hash value for @var{key}. This is a number in the range +@math{0} to @math{@var{size}-1}, which is suitable for use in a hash +table of the given @var{size}. + +Note that @code{hashq} and @code{hashv} may use internal addresses of +objects, so if an object is garbage collected and re-created it can +have a different hash value, even when the two are notionally +@code{eq?}. For instance with symbols, + +@example +(hashq 'something 123) @result{} 19 +(gc) +(hashq 'something 123) @result{} 62 +@end example + +In normal use this is not a problem, since an object entered into a +hash table won't be garbage collected until removed. It's only if +hashing calculations are somehow separated from normal references that +its lifetime needs to be considered. +@end deffn + +@deffn {Scheme Procedure} hash-get-handle table key +@deffnx {Scheme Procedure} hashq-get-handle table key +@deffnx {Scheme Procedure} hashv-get-handle table key +@deffnx {Scheme Procedure} hashx-get-handle hash assoc table key +@deffnx {C Function} scm_hash_get_handle (table, key) +@deffnx {C Function} scm_hashq_get_handle (table, key) +@deffnx {C Function} scm_hashv_get_handle (table, key) +@deffnx {C Function} scm_hashx_get_handle (hash, assoc, table, key) +Return the @code{(@var{key} . @var{value})} pair for @var{key} in the +given hash @var{table}, or @code{#f} if @var{key} is not in +@var{table}. +@end deffn + +@deffn {Scheme Procedure} hash-create-handle! table key init +@deffnx {Scheme Procedure} hashq-create-handle! table key init +@deffnx {Scheme Procedure} hashv-create-handle! table key init +@deffnx {Scheme Procedure} hashx-create-handle! hash assoc table key init +@deffnx {C Function} scm_hash_create_handle_x (table, key, init) +@deffnx {C Function} scm_hashq_create_handle_x (table, key, init) +@deffnx {C Function} scm_hashv_create_handle_x (table, key, init) +@deffnx {C Function} scm_hashx_create_handle_x (hash, assoc, table, key, init) +Return the @code{(@var{key} . @var{value})} pair for @var{key} in the +given hash @var{table}. If @var{key} is not in @var{table} then +create an entry for it with @var{init} as the value, and return that +pair. +@end deffn + +@deffn {Scheme Procedure} hash-map->list proc table +@deffnx {Scheme Procedure} hash-for-each proc table +@deffnx {C Function} scm_hash_map_to_list (proc, table) +@deffnx {C Function} scm_hash_for_each (proc, table) +Apply @var{proc} to the entries in the given hash @var{table}. Each +call is @code{(@var{proc} @var{key} @var{value})}. @code{hash-map->list} +returns a list of the results from these calls, @code{hash-for-each} +discards the results and returns an unspecified value. + +Calls are made over the table entries in an unspecified order, and for +@code{hash-map->list} the order of the values in the returned list is +unspecified. Results will be unpredictable if @var{table} is modified +while iterating. + +For example the following returns a new alist comprising all the +entries from @code{mytable}, in no particular order. + +@example +(hash-map->list cons mytable) +@end example +@end deffn + +@deffn {Scheme Procedure} hash-for-each-handle proc table +@deffnx {C Function} scm_hash_for_each_handle (proc, table) +Apply @var{proc} to the entries in the given hash @var{table}. Each +call is @code{(@var{proc} @var{handle})}, where @var{handle} is a +@code{(@var{key} . @var{value})} pair. Return an unspecified value. + +@code{hash-for-each-handle} differs from @code{hash-for-each} only in +the argument list of @var{proc}. +@end deffn + +@deffn {Scheme Procedure} hash-fold proc init table +@deffnx {C Function} scm_hash_fold (proc, init, table) +Accumulate a result by applying @var{proc} to the elements of the +given hash @var{table}. Each call is @code{(@var{proc} @var{key} +@var{value} @var{prior-result})}, where @var{key} and @var{value} are +from the @var{table} and @var{prior-result} is the return from the +previous @var{proc} call. For the first call, @var{prior-result} is +the given @var{init} value. + +Calls are made over the table entries in an unspecified order. +Results will be unpredictable if @var{table} is modified while +@code{hash-fold} is running. + +For example, the following returns a count of how many keys in +@code{mytable} are strings. + +@example +(hash-fold (lambda (key value prior) + (if (string? key) (1+ prior) prior)) + 0 mytable) +@end example +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/api-control.texi b/doc/ref/api-control.texi new file mode 100644 index 000000000..cbc386a05 --- /dev/null +++ b/doc/ref/api-control.texi @@ -0,0 +1,1337 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Control Mechanisms +@section Controlling the Flow of Program Execution + +See @ref{Control Flow} for a discussion of how the more general control +flow of Scheme affects C code. + +@menu +* begin:: Evaluating a sequence of expressions. +* if cond case:: Simple conditional evaluation. +* and or:: Conditional evaluation of a sequence. +* while do:: Iteration mechanisms. +* Continuations:: Continuations. +* Multiple Values:: Returning and accepting multiple values. +* Exceptions:: Throwing and catching exceptions. +* Error Reporting:: Procedures for signaling errors. +* Dynamic Wind:: Guarding against non-local entrance/exit. +* Frames:: Another way to handle non-localness +* Handling Errors:: How to handle errors in C code. +@end menu + +@node begin +@subsection Evaluating a Sequence of Expressions + +@cindex begin +@cindex sequencing +@cindex expression sequencing + +The @code{begin} syntax is used for grouping several expressions +together so that they are treated as if they were one expression. +This is particularly important when syntactic expressions are used +which only allow one expression, but the programmer wants to use more +than one expression in that place. As an example, consider the +conditional expression below: + +@lisp +(if (> x 0) + (begin (display "greater") (newline))) +@end lisp + +If the two calls to @code{display} and @code{newline} were not embedded +in a @code{begin}-statement, the call to @code{newline} would get +misinterpreted as the else-branch of the @code{if}-expression. + +@deffn syntax begin expr1 expr2 @dots{} +The expression(s) are evaluated in left-to-right order and the value +of the last expression is returned as the value of the +@code{begin}-expression. This expression type is used when the +expressions before the last one are evaluated for their side effects. + +Guile also allows the expression @code{(begin)}, a @code{begin} with no +sub-expressions. Such an expression returns the `unspecified' value. +@end deffn + +@node if cond case +@subsection Simple Conditional Evaluation + +@cindex conditional evaluation +@cindex if +@cindex case +@cindex cond + +Guile provides three syntactic constructs for conditional evaluation. +@code{if} is the normal if-then-else expression (with an optional else +branch), @code{cond} is a conditional expression with multiple branches +and @code{case} branches if an expression has one of a set of constant +values. + +@deffn syntax if test consequent [alternate] +All arguments may be arbitrary expressions. First, @var{test} is +evaluated. If it returns a true value, the expression @var{consequent} +is evaluated and @var{alternate} is ignored. If @var{test} evaluates to +@code{#f}, @var{alternate} is evaluated instead. The value of the +evaluated branch (@var{consequent} or @var{alternate}) is returned as +the value of the @code{if} expression. + +When @var{alternate} is omitted and the @var{test} evaluates to +@code{#f}, the value of the expression is not specified. +@end deffn + +@deffn syntax cond clause1 clause2 @dots{} +Each @code{cond}-clause must look like this: + +@lisp +(@var{test} @var{expression} @dots{}) +@end lisp + +where @var{test} and @var{expression} are arbitrary expression, or like +this + +@lisp +(@var{test} => @var{expression}) +@end lisp + +where @var{expression} must evaluate to a procedure. + +The @var{test}s of the clauses are evaluated in order and as soon as one +of them evaluates to a true values, the corresponding @var{expression}s +are evaluated in order and the last value is returned as the value of +the @code{cond}-expression. For the @code{=>} clause type, +@var{expression} is evaluated and the resulting procedure is applied to +the value of @var{test}. The result of this procedure application is +then the result of the @code{cond}-expression. + +The @var{test} of the last @var{clause} may be the symbol @code{else}. +Then, if none of the preceding @var{test}s is true, the +@var{expression}s following the @code{else} are evaluated to produce the +result of the @code{cond}-expression. +@end deffn + +@deffn syntax case key clause1 clause2 @dots{} +@var{key} may be any expression, the @var{clause}s must have the form + +@lisp +((@var{datum1} @dots{}) @var{expr1} @var{expr2} @dots{}) +@end lisp + +and the last @var{clause} may have the form + +@lisp +(else @var{expr1} @var{expr2} @dots{}) +@end lisp + +All @var{datum}s must be distinct. First, @var{key} is evaluated. The +the result of this evaluation is compared against all @var{datum}s using +@code{eqv?}. When this comparison succeeds, the expression(s) following +the @var{datum} are evaluated from left to right, returning the value of +the last expression as the result of the @code{case} expression. + +If the @var{key} matches no @var{datum} and there is an +@code{else}-clause, the expressions following the @code{else} are +evaluated. If there is no such clause, the result of the expression is +unspecified. +@end deffn + + +@node and or +@subsection Conditional Evaluation of a Sequence of Expressions + +@code{and} and @code{or} evaluate all their arguments in order, similar +to @code{begin}, but evaluation stops as soon as one of the expressions +evaluates to false or true, respectively. + +@deffn syntax and expr @dots{} +Evaluate the @var{expr}s from left to right and stop evaluation as soon +as one expression evaluates to @code{#f}; the remaining expressions are +not evaluated. The value of the last evaluated expression is returned. +If no expression evaluates to @code{#f}, the value of the last +expression is returned. + +If used without expressions, @code{#t} is returned. +@end deffn + +@deffn syntax or expr @dots{} +Evaluate the @var{expr}s from left to right and stop evaluation as soon +as one expression evaluates to a true value (that is, a value different +from @code{#f}); the remaining expressions are not evaluated. The value +of the last evaluated expression is returned. If all expressions +evaluate to @code{#f}, @code{#f} is returned. + +If used without expressions, @code{#f} is returned. +@end deffn + + +@node while do +@subsection Iteration mechanisms + +@cindex iteration +@cindex looping +@cindex named let + +Scheme has only few iteration mechanisms, mainly because iteration in +Scheme programs is normally expressed using recursion. Nevertheless, +R5RS defines a construct for programming loops, calling @code{do}. In +addition, Guile has an explicit looping syntax called @code{while}. + +@deffn syntax do ((variable init [step]) @dots{}) (test [expr @dots{}]) body @dots{} +Bind @var{variable}s and evaluate @var{body} until @var{test} is true. +The return value is the last @var{expr} after @var{test}, if given. A +simple example will illustrate the basic form, + +@example +(do ((i 1 (1+ i))) + ((> i 4)) + (display i)) +@print{} 1234 +@end example + +@noindent +Or with two variables and a final return value, + +@example +(do ((i 1 (1+ i)) + (p 3 (* 3 p))) + ((> i 4) + p) + (format #t "3**~s is ~s\n" i p)) +@print{} +3**1 is 3 +3**2 is 9 +3**3 is 27 +3**4 is 81 +@result{} +789 +@end example + +The @var{variable} bindings are established like a @code{let}, in that +the expressions are all evaluated and then all bindings made. When +iterating, the optional @var{step} expressions are evaluated with the +previous bindings in scope, then new bindings all made. + +The @var{test} expression is a termination condition. Looping stops +when the @var{test} is true. It's evaluated before running the +@var{body} each time, so if it's true the first time then @var{body} +is not run at all. + +The optional @var{expr}s after the @var{test} are evaluated at the end +of looping, with the final @var{variable} bindings available. The +last @var{expr} gives the return value, or if there are no @var{expr}s +the return value is unspecified. + +Each iteration establishes bindings to fresh locations for the +@var{variable}s, like a new @code{let} for each iteration. This is +done for @var{variable}s without @var{step} expressions too. The +following illustrates this, showing how a new @code{i} is captured by +the @code{lambda} in each iteration (@pxref{About Closure,, The +Concept of Closure}). + +@example +(define lst '()) +(do ((i 1 (1+ i))) + ((> i 4)) + (set! lst (cons (lambda () i) lst))) +(map (lambda (proc) (proc)) lst) +@result{} +(4 3 2 1) +@end example +@end deffn + +@deffn syntax while cond body @dots{} +Run a loop executing the @var{body} forms while @var{cond} is true. +@var{cond} is tested at the start of each iteration, so if it's +@code{#f} the first time then @var{body} is not executed at all. The +return value is unspecified. + +Within @code{while}, two extra bindings are provided, they can be used +from both @var{cond} and @var{body}. + +@deffn {Scheme Procedure} break +Break out of the @code{while} form. +@end deffn + +@deffn {Scheme Procedure} continue +Abandon the current iteration, go back to the start and test +@var{cond} again, etc. +@end deffn + +Each @code{while} form gets its own @code{break} and @code{continue} +procedures, operating on that @code{while}. This means when loops are +nested the outer @code{break} can be used to escape all the way out. +For example, + +@example +(while (test1) + (let ((outer-break break)) + (while (test2) + (if (something) + (outer-break #f)) + ...))) +@end example + +Note that each @code{break} and @code{continue} procedure can only be +used within the dynamic extent of its @code{while}. Outside the +@code{while} their behaviour is unspecified. +@end deffn + +@cindex named let +Another very common way of expressing iteration in Scheme programs is +the use of the so-called @dfn{named let}. + +Named let is a variant of @code{let} which creates a procedure and calls +it in one step. Because of the newly created procedure, named let is +more powerful than @code{do}--it can be used for iteration, but also +for arbitrary recursion. + +@deffn syntax let variable bindings body +For the definition of @var{bindings} see the documentation about +@code{let} (@pxref{Local Bindings}). + +Named @code{let} works as follows: + +@itemize @bullet +@item +A new procedure which accepts as many arguments as are in @var{bindings} +is created and bound locally (using @code{let}) to @var{variable}. The +new procedure's formal argument names are the name of the +@var{variables}. + +@item +The @var{body} expressions are inserted into the newly created procedure. + +@item +The procedure is called with the @var{init} expressions as the formal +arguments. +@end itemize + +The next example implements a loop which iterates (by recursion) 1000 +times. + +@lisp +(let lp ((x 1000)) + (if (positive? x) + (lp (- x 1)) + x)) +@result{} +0 +@end lisp +@end deffn + + +@node Continuations +@subsection Continuations +@cindex continuations + +A ``continuation'' is the code that will execute when a given function +or expression returns. For example, consider + +@example +(define (foo) + (display "hello\n") + (display (bar)) (newline) + (exit)) +@end example + +The continuation from the call to @code{bar} comprises a +@code{display} of the value returned, a @code{newline} and an +@code{exit}. This can be expressed as a function of one argument. + +@example +(lambda (r) + (display r) (newline) + (exit)) +@end example + +In Scheme, continuations are represented as special procedures just +like this. The special property is that when a continuation is called +it abandons the current program location and jumps directly to that +represented by the continuation. + +A continuation is like a dynamic label, capturing at run-time a point +in program execution, including all the nested calls that have lead to +it (or rather the code that will execute when those calls return). + +Continuations are created with the following functions. + +@deffn {Scheme Procedure} call-with-current-continuation proc +@deffnx {Scheme Procedure} call/cc proc +@rnindex call-with-current-continuation +Capture the current continuation and call @code{(@var{proc} +@var{cont})} with it. The return value is the value returned by +@var{proc}, or when @code{(@var{cont} @var{value})} is later invoked, +the return is the @var{value} passed. + +Normally @var{cont} should be called with one argument, but when the +location resumed is expecting multiple values (@pxref{Multiple +Values}) then they should be passed as multiple arguments, for +instance @code{(@var{cont} @var{x} @var{y} @var{z})}. + +@var{cont} may only be used from the dynamic root in which it was +created (@pxref{Dynamic Roots}), and in a multi-threaded program only +from the thread in which it was created, since each thread is a +separate dynamic root. + +The call to @var{proc} is not part of the continuation captured, it runs +only when the continuation is created. Often a program will want to +store @var{cont} somewhere for later use; this can be done in +@var{proc}. + +The @code{call} in the name @code{call-with-current-continuation} +refers to the way a call to @var{proc} gives the newly created +continuation. It's not related to the way a call is used later to +invoke that continuation. + +@code{call/cc} is an alias for @code{call-with-current-continuation}. +This is in common use since the latter is rather long. +@end deffn + +@deftypefn {C Function} SCM scm_make_continuation (int *first) +Capture the current continuation as described above. The return value +is the new continuation, and @var{*first} is set to 1. + +When the continuation is invoked, @code{scm_make_continuation} will +return again, this time returning the value (or set of multiple +values) passed in that invocation, and with @var{*first} set to 0. +@end deftypefn + +@sp 1 +@noindent +Here is a simple example, + +@example +(define kont #f) +(format #t "the return is ~a\n" + (call/cc (lambda (k) + (set! kont k) + 1))) +@result{} the return is 1 + +(kont 2) +@result{} the return is 2 +@end example + +@code{call/cc} captures a continuation in which the value returned is +going to be displayed by @code{format}. The @code{lambda} stores this +in @code{kont} and gives an initial return @code{1} which is +displayed. The later invocation of @code{kont} resumes the captured +point, but this time returning @code{2}, which is displayed. + +When Guile is run interactively, a call to @code{format} like this has +an implicit return back to the read-eval-print loop. @code{call/cc} +captures that like any other return, which is why interactively +@code{kont} will come back to read more input. + +@sp 1 +C programmers may note that @code{call/cc} is like @code{setjmp} in +the way it records at runtime a point in program execution. A call to +a continuation is like a @code{longjmp} in that it abandons the +present location and goes to the recorded one. Like @code{longjmp}, +the value passed to the continuation is the value returned by +@code{call/cc} on resuming there. However @code{longjmp} can only go +up the program stack, but the continuation mechanism can go anywhere. + +When a continuation is invoked, @code{call/cc} and subsequent code +effectively ``returns'' a second time. It can be confusing to imagine +a function returning more times than it was called. It may help +instead to think of it being stealthily re-entered and then program +flow going on as normal. + +@code{dynamic-wind} (@pxref{Dynamic Wind}) can be used to ensure setup +and cleanup code is run when a program locus is resumed or abandoned +through the continuation mechanism. C code can use @dfn{frames} +(@pxref{Frames}). + +@sp 1 +Continuations are a powerful mechanism, and can be used to implement +almost any sort of control structure, such as loops, coroutines, or +exception handlers. + +However the implementation of continuations in Guile is not as +efficient as one might hope, because Guile is designed to cooperate +with programs written in other languages, such as C, which do not know +about continuations. Basically continuations are captured by a block +copy of the stack, and resumed by copying back. + +For this reason, generally continuations should be used only when +there is no other simple way to achieve the desired result, or when +the elegance of the continuation mechanism outweighs the need for +performance. + +Escapes upwards from loops or nested functions are generally best +handled with exceptions (@pxref{Exceptions}). Coroutines can be +efficiently implemented with cooperating threads (a thread holds a +full program stack but doesn't copy it around the way continuations +do). + + +@node Multiple Values +@subsection Returning and Accepting Multiple Values + +@cindex multiple values +@cindex receive + +Scheme allows a procedure to return more than one value to its caller. +This is quite different to other languages which only allow +single-value returns. Returning multiple values is different from +returning a list (or pair or vector) of values to the caller, because +conceptually not @emph{one} compound object is returned, but several +distinct values. + +The primitive procedures for handling multiple values are @code{values} +and @code{call-with-values}. @code{values} is used for returning +multiple values from a procedure. This is done by placing a call to +@code{values} with zero or more arguments in tail position in a +procedure body. @code{call-with-values} combines a procedure returning +multiple values with a procedure which accepts these values as +parameters. + +@rnindex values +@deffn {Scheme Procedure} values arg1 @dots{} argN +@deffnx {C Function} scm_values (args) +Delivers all of its arguments to its continuation. Except for +continuations created by the @code{call-with-values} procedure, +all continuations take exactly one value. The effect of +passing no value or more than one value to continuations that +were not created by @code{call-with-values} is unspecified. + +For @code{scm_values}, @var{args} is a list of arguments and the +return is a multiple-values object which the caller can return. In +the current implementation that object shares structure with +@var{args}, so @var{args} should not be modified subsequently. +@end deffn + +@rnindex call-with-values +@deffn {Scheme Procedure} call-with-values producer consumer +Calls its @var{producer} argument with no values and a +continuation that, when passed some values, calls the +@var{consumer} procedure with those values as arguments. The +continuation for the call to @var{consumer} is the continuation +of the call to @code{call-with-values}. + +@example +(call-with-values (lambda () (values 4 5)) + (lambda (a b) b)) +@result{} 5 + +@end example +@example +(call-with-values * -) +@result{} -1 +@end example +@end deffn + +In addition to the fundamental procedures described above, Guile has a +module which exports a syntax called @code{receive}, which is much more +convenient. If you want to use it in your programs, you have to load +the module @code{(ice-9 receive)} with the statement + +@lisp +(use-modules (ice-9 receive)) +@end lisp + +@deffn {library syntax} receive formals expr body @dots{} +Evaluate the expression @var{expr}, and bind the result values (zero or +more) to the formal arguments in the formal argument list @var{formals}. +@var{formals} must have the same syntax like the formal argument list +used in @code{lambda} (@pxref{Lambda}). After binding the variables, +the expressions in @var{body} @dots{} are evaluated in order. +@end deffn + + +@node Exceptions +@subsection Exceptions +@cindex error handling +@cindex exception handling + +A common requirement in applications is to want to jump +@dfn{non-locally} from the depths of a computation back to, say, the +application's main processing loop. Usually, the place that is the +target of the jump is somewhere in the calling stack of procedures that +called the procedure that wants to jump back. For example, typical +logic for a key press driven application might look something like this: + +@example +main-loop: + read the next key press and call dispatch-key + +dispatch-key: + lookup the key in a keymap and call an appropriate procedure, + say find-file + +find-file: + interactively read the required file name, then call + find-specified-file + +find-specified-file: + check whether file exists; if not, jump back to main-loop + @dots{} +@end example + +The jump back to @code{main-loop} could be achieved by returning through +the stack one procedure at a time, using the return value of each +procedure to indicate the error condition, but Guile (like most modern +programming languages) provides an additional mechanism called +@dfn{exception handling} that can be used to implement such jumps much +more conveniently. + +@menu +* Exception Terminology:: Different ways to say the same thing. +* Catch:: Setting up to catch exceptions. +* Throw:: Throwing an exception. +* Lazy Catch:: Catch without unwinding the stack. +* Exception Implementation:: How Guile implements exceptions. +@end menu + + +@node Exception Terminology +@subsubsection Exception Terminology + +There are several variations on the terminology for dealing with +non-local jumps. It is useful to be aware of them, and to realize +that they all refer to the same basic mechanism. + +@itemize @bullet +@item +Actually making a non-local jump may be called @dfn{raising an +exception}, @dfn{raising a signal}, @dfn{throwing an exception} or +@dfn{doing a long jump}. When the jump indicates an error condition, +people may talk about @dfn{signalling}, @dfn{raising} or @dfn{throwing} +@dfn{an error}. + +@item +Handling the jump at its target may be referred to as @dfn{catching} or +@dfn{handling} the @dfn{exception}, @dfn{signal} or, where an error +condition is involved, @dfn{error}. +@end itemize + +Where @dfn{signal} and @dfn{signalling} are used, special care is needed +to avoid the risk of confusion with POSIX signals. + +This manual prefers to speak of throwing and catching exceptions, since +this terminology matches the corresponding Guile primitives. + + +@node Catch +@subsubsection Catching Exceptions + +@code{catch} is used to set up a target for a possible non-local jump. +The arguments of a @code{catch} expression are a @dfn{key}, which +restricts the set of exceptions to which this @code{catch} applies, a +thunk that specifies the code to execute and a @dfn{handler} procedure +that says what to do if an exception is thrown while executing the code. +Note that if the execution thunk executes @dfn{normally}, which means +without throwing any exceptions, the handler procedure is not called at +all. + +When an exception is thrown using the @code{throw} function, the first +argument of the @code{throw} is a symbol that indicates the type of the +exception. For example, Guile throws an exception using the symbol +@code{numerical-overflow} to indicate numerical overflow errors such as +division by zero: + +@lisp +(/ 1 0) +@result{} +ABORT: (numerical-overflow) +@end lisp + +The @var{key} argument in a @code{catch} expression corresponds to this +symbol. @var{key} may be a specific symbol, such as +@code{numerical-overflow}, in which case the @code{catch} applies +specifically to exceptions of that type; or it may be @code{#t}, which +means that the @code{catch} applies to all exceptions, irrespective of +their type. + +The second argument of a @code{catch} expression should be a thunk +(i.e. a procedure that accepts no arguments) that specifies the normal +case code. The @code{catch} is active for the execution of this thunk, +including any code called directly or indirectly by the thunk's body. +Evaluation of the @code{catch} expression activates the catch and then +calls this thunk. + +The third argument of a @code{catch} expression is a handler procedure. +If an exception is thrown, this procedure is called with exactly the +arguments specified by the @code{throw}. Therefore, the handler +procedure must be designed to accept a number of arguments that +corresponds to the number of arguments in all @code{throw} expressions +that can be caught by this @code{catch}. + +@deffn {Scheme Procedure} catch key thunk handler +@deffnx {C Function} scm_catch (key, thunk, handler) +Invoke @var{thunk} in the dynamic context of @var{handler} for +exceptions matching @var{key}. If thunk throws to the symbol +@var{key}, then @var{handler} is invoked this way: +@lisp +(handler key args ...) +@end lisp + +@var{key} is a symbol or @code{#t}. + +@var{thunk} takes no arguments. If @var{thunk} returns +normally, that is the return value of @code{catch}. + +Handler is invoked outside the scope of its own @code{catch}. +If @var{handler} again throws to the same key, a new handler +from further up the call chain is invoked. + +If the key is @code{#t}, then a throw to @emph{any} symbol will +match this call to @code{catch}. +@end deffn + +If the handler procedure needs to match a variety of @code{throw} +expressions with varying numbers of arguments, you should write it like +this: + +@lisp +(lambda (key . args) + @dots{}) +@end lisp + +@noindent +The @var{key} argument is guaranteed always to be present, because a +@code{throw} without a @var{key} is not valid. The number and +interpretation of the @var{args} varies from one type of exception to +another, but should be specified by the documentation for each exception +type. + +Note that, once the handler procedure is invoked, the catch that led to +the handler procedure being called is no longer active. Therefore, if +the handler procedure itself throws an exception, that exception can +only be caught by another active catch higher up the call stack, if +there is one. + +@sp 1 +@deftypefn {C Function} SCM scm_internal_catch (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data) +The above @code{scm_catch} takes Scheme procedures as body and handler +arguments. @code{scm_internal_catch} is an equivalent taking C +functions. + +@var{body} is called as @code{@var{body} (@var{body_data})} with a +catch on exceptions of the given @var{tag} type. If an exception is +caught, @var{handler} is called @code{@var{handler} +(@var{handler_data}, @var{key}, @var{args})}. @var{key} and +@var{args} are the @code{SCM} key and argument list from the +@code{throw}. + +@tpindex scm_t_catch_body +@tpindex scm_t_catch_handler +@var{body} and @var{handler} should have the following prototypes. +@code{scm_t_catch_body} and @code{scm_t_catch_handler} are pointer +typedefs for these. + +@example +SCM body (void *data); +SCM handler (void *data, SCM key, SCM args); +@end example + +The @var{body_data} and @var{handler_data} parameters are passed to +the respective calls so an application can communicate extra +information to those functions. + +If the data consists of an @code{SCM} object, care should be taken +that it isn't garbage collected while still required. If the +@code{SCM} is a local C variable, one way to protect it is to pass a +pointer to that variable as the data parameter, since the C compiler +will then know the value must be held on the stack. Another way is to +use @code{scm_remember_upto_here_1} (@pxref{Remembering During +Operations}). +@end deftypefn + + +@node Throw +@subsubsection Throwing Exceptions + +The @code{throw} primitive is used to throw an exception. One argument, +the @var{key}, is mandatory, and must be a symbol; it indicates the type +of exception that is being thrown. Following the @var{key}, +@code{throw} accepts any number of additional arguments, whose meaning +depends on the exception type. The documentation for each possible type +of exception should specify the additional arguments that are expected +for that kind of exception. + +@deffn {Scheme Procedure} throw key . args +@deffnx {C Function} scm_throw (key, args) +Invoke the catch form matching @var{key}, passing @var{args} to the +@var{handler}. + +@var{key} is a symbol. It will match catches of the same symbol or of +@code{#t}. + +If there is no handler at all, Guile prints an error and then exits. +@end deffn + +When an exception is thrown, it will be caught by the innermost +@code{catch} expression that applies to the type of the thrown +exception; in other words, the innermost @code{catch} whose @var{key} is +@code{#t} or is the same symbol as that used in the @code{throw} +expression. Once Guile has identified the appropriate @code{catch}, it +handles the exception by applying that @code{catch} expression's handler +procedure to the arguments of the @code{throw}. + +If there is no appropriate @code{catch} for a thrown exception, Guile +prints an error to the current error port indicating an uncaught +exception, and then exits. In practice, it is quite difficult to +observe this behaviour, because Guile when used interactively installs a +top level @code{catch} handler that will catch all exceptions and print +an appropriate error message @emph{without} exiting. For example, this +is what happens if you try to throw an unhandled exception in the +standard Guile REPL; note that Guile's command loop continues after the +error message: + +@lisp +guile> (throw 'badex) +<unnamed port>:3:1: In procedure gsubr-apply @dots{} +<unnamed port>:3:1: unhandled-exception: badex +ABORT: (misc-error) +guile> +@end lisp + +The default uncaught exception behaviour can be observed by evaluating a +@code{throw} expression from the shell command line: + +@example +$ guile -c "(begin (throw 'badex) (display \"here\\n\"))" +guile: uncaught throw to badex: () +$ +@end example + +@noindent +That Guile exits immediately following the uncaught exception +is shown by the absence of any output from the @code{display} +expression, because Guile never gets to the point of evaluating that +expression. + + +@node Lazy Catch +@subsubsection Catch Without Unwinding + +A @dfn{lazy catch} is used in the same way as a normal @code{catch}, +with @var{key}, @var{thunk} and @var{handler} arguments specifying the +exception type, normal case code and handler procedure, but differs in +one important respect: the handler procedure is executed without +unwinding the call stack from the context of the @code{throw} expression +that caused the handler to be invoked. + +@deffn {Scheme Procedure} lazy-catch key thunk handler +@deffnx {C Function} scm_lazy_catch (key, thunk, handler) +This behaves exactly like @code{catch}, except that it does +not unwind the stack before invoking @var{handler}. +The @var{handler} procedure is not allowed to return: +it must throw to another catch, or otherwise exit non-locally. +@end deffn + +@deftypefn {C Function} SCM scm_internal_lazy_catch (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data) +The above @code{scm_lazy_catch} takes Scheme procedures as body and +handler arguments. @code{scm_internal_lazy_catch} is an equivalent +taking C functions. See @code{scm_internal_catch} (@pxref{Catch}) for +a description of the parameters, the behaviour however of course +follows @code{lazy-catch}. +@end deftypefn + +Typically, @var{handler} should save any desired state associated with +the stack at the point where the corresponding @code{throw} occurred, +and then throw an exception itself --- usually the same exception as the +one it caught. If @var{handler} is invoked and does @emph{not} throw an +exception, Guile itself throws an exception with key @code{misc-error}. + +Not unwinding the stack means that throwing an exception that is caught +by a @code{lazy-catch} is @emph{almost} equivalent to calling the +@code{lazy-catch}'s handler inline instead of each @code{throw}, and +then omitting the surrounding @code{lazy-catch}. In other words, + +@lisp +(lazy-catch 'key + (lambda () @dots{} (throw 'key args @dots{}) @dots{}) + handler) +@end lisp + +@noindent +is @emph{almost} equivalent to + +@lisp +((lambda () @dots{} (handler 'key args @dots{}) @dots{})) +@end lisp + +@noindent +But why only @emph{almost}? The difference is that with +@code{lazy-catch} (as with normal @code{catch}), the dynamic context is +unwound back to just outside the @code{lazy-catch} expression before +invoking the handler. (For an introduction to what is meant by dynamic +context, @xref{Dynamic Wind}.) + +Then, when the handler @emph{itself} throws an exception, that exception +must be caught by some kind of @code{catch} (including perhaps another +@code{lazy-catch}) higher up the call stack. + +The dynamic context also includes @code{with-fluids} blocks (REFFIXME), +so the effect of unwinding the dynamic context can also be seen in fluid +variable values. This is illustrated by the following code, in which +the normal case thunk uses @code{with-fluids} to temporarily change the +value of a fluid: + +@lisp +(define f (make-fluid)) +(fluid-set! f "top level value") + +(define (handler . args) + (cons (fluid-ref f) args)) + +(lazy-catch 'foo + (lambda () + (with-fluids ((f "local value")) + (throw 'foo))) + handler) +@result{} +("top level value" foo) + +((lambda () + (with-fluids ((f "local value")) + (handler 'foo)))) +@result{} +("local value" foo) +@end lisp + +@noindent +In the @code{lazy-catch} version, the unwinding of dynamic context +restores @code{f} to its value outside the @code{with-fluids} block +before the handler is invoked, so the handler's @code{(fluid-ref f)} +returns the external value. + +@code{lazy-catch} is useful because it permits the implementation of +debuggers and other reflective programming tools that need to access the +state of the call stack at the exact point where an exception or an +error is thrown. For an example of this, see REFFIXME:stack-catch. + + +@node Exception Implementation +@subsubsection How Guile Implements Exceptions + +It is traditional in Scheme to implement exception systems using +@code{call-with-current-continuation}. Continuations +(@pxref{Continuations}) are such a powerful concept that any other +control mechanism --- including @code{catch} and @code{throw} --- can be +implemented in terms of them. + +Guile does not implement @code{catch} and @code{throw} like this, +though. Why not? Because Guile is specifically designed to be easy to +integrate with applications written in C. In a mixed Scheme/C +environment, the concept of @dfn{continuation} must logically include +``what happens next'' in the C parts of the application as well as the +Scheme parts, and it turns out that the only reasonable way of +implementing continuations like this is to save and restore the complete +C stack. + +So Guile's implementation of @code{call-with-current-continuation} is a +stack copying one. This allows it to interact well with ordinary C +code, but means that creating and calling a continuation is slowed down +by the time that it takes to copy the C stack. + +The more targeted mechanism provided by @code{catch} and @code{throw} +does not need to save and restore the C stack because the @code{throw} +always jumps to a location higher up the stack of the code that executes +the @code{throw}. Therefore Guile implements the @code{catch} and +@code{throw} primitives independently of +@code{call-with-current-continuation}, in a way that takes advantage of +this @emph{upwards only} nature of exceptions. + + +@node Error Reporting +@subsection Procedures for Signaling Errors + +Guile provides a set of convenience procedures for signaling error +conditions that are implemented on top of the exception primitives just +described. + +@deffn {Scheme Procedure} error msg args @dots{} +Raise an error with key @code{misc-error} and a message constructed by +displaying @var{msg} and writing @var{args}. +@end deffn + +@deffn {Scheme Procedure} scm-error key subr message args data +@deffnx {C Function} scm_error_scm (key, subr, message, args, data) +Raise an error with key @var{key}. @var{subr} can be a string +naming the procedure associated with the error, or @code{#f}. +@var{message} is the error message string, possibly containing +@code{~S} and @code{~A} escapes. When an error is reported, +these are replaced by formatting the corresponding members of +@var{args}: @code{~A} (was @code{%s} in older versions of +Guile) formats using @code{display} and @code{~S} (was +@code{%S}) formats using @code{write}. @var{data} is a list or +@code{#f} depending on @var{key}: if @var{key} is +@code{system-error} then it should be a list containing the +Unix @code{errno} value; If @var{key} is @code{signal} then it +should be a list containing the Unix signal number; otherwise +it will usually be @code{#f}. +@end deffn + +@deffn {Scheme Procedure} strerror err +@deffnx {C Function} scm_strerror (err) +Return the Unix error message corresponding to @var{err}, which +must be an integer value. +@end deffn + +@c begin (scm-doc-string "boot-9.scm" "false-if-exception") +@deffn syntax false-if-exception expr +Returns the result of evaluating its argument; however +if an exception occurs then @code{#f} is returned instead. +@end deffn +@c end + + +@node Dynamic Wind +@subsection Dynamic Wind + +@rnindex dynamic-wind +@deffn {Scheme Procedure} dynamic-wind in_guard thunk out_guard +@deffnx {C Function} scm_dynamic_wind (in_guard, thunk, out_guard) +All three arguments must be 0-argument procedures. +@var{in_guard} is called, then @var{thunk}, then +@var{out_guard}. + +If, any time during the execution of @var{thunk}, the +dynamic extent of the @code{dynamic-wind} expression is escaped +non-locally, @var{out_guard} is called. If the dynamic extent of +the dynamic-wind is re-entered, @var{in_guard} is called. Thus +@var{in_guard} and @var{out_guard} may be called any number of +times. +@lisp +(define x 'normal-binding) +@result{} x +(define a-cont (call-with-current-continuation + (lambda (escape) + (let ((old-x x)) + (dynamic-wind + ;; in-guard: + ;; + (lambda () (set! x 'special-binding)) + + ;; thunk + ;; + (lambda () (display x) (newline) + (call-with-current-continuation escape) + (display x) (newline) + x) + + ;; out-guard: + ;; + (lambda () (set! x old-x))))))) + +;; Prints: +special-binding +;; Evaluates to: +@result{} a-cont +x +@result{} normal-binding +(a-cont #f) +;; Prints: +special-binding +;; Evaluates to: +@result{} a-cont ;; the value of the (define a-cont...) +x +@result{} normal-binding +a-cont +@result{} special-binding +@end lisp +@end deffn + +@node Frames +@subsection Frames + +For Scheme code, the fundamental procedure to react to non-local entry +and exits of dynamic contexts is @code{dynamic-wind}. C code could use +@code{scm_internal_dynamic_wind}, but since C does not allow the +convenient construction of anonymous procedures that close over lexical +variables, this will be, well, inconvenient. Instead, C code can use +@dfn{frames}. + +Guile offers the functions @code{scm_frame_begin} and +@code{scm_frame_end} to delimit a dynamic extent. Within this dynamic +extent, which is called a @dfn{frame}, you can perform various +@dfn{frame actions} that control what happens when the frame is entered +or left. For example, you can register a cleanup routine with +@code{scm_frame_unwind} that is executed when the frame is left. There are +several other more specialized frame actions as well, for example to +temporarily block the execution of asyncs or to temporarily change the +current output port. They are described elsewhere in this manual. + +Here is an example that shows how to prevent memory leaks. + +@example + +/* Suppose there is a function called FOO in some library that you + would like to make available to Scheme code (or to C code that + follows the Scheme conventions). + + FOO takes two C strings and returns a new string. When an error has + occurred in FOO, it returns NULL. +*/ + +char *foo (char *s1, char *s2); + +/* SCM_FOO interfaces the C function FOO to the Scheme way of life. + It takes care to free up all temporary strings in the case of + non-local exits. + + It uses SCM_TO_STRING as a helper procedure. + */ + +char * +scm_to_string (SCM obj) +@{ + if (SCM_STRINGP (obj)) + @{ + char *res = scm_malloc (SCM_STRING_LENGTH (obj)+1); + strcpy (res, SCM_STRING_CHARS (obj)); + scm_remember_upto_here_1 (obj); + return res; + @} + else + scm_wrong_type_arg ("scm_to_string", 1, obj); +@} + +SCM +scm_foo (SCM s1, SCM s2) +@{ + char *c_s1, *c_s2, *c_res; + + scm_frame_begin (0); + + c_s1 = scm_to_string (s1); + scm_frame_unwind_handler (free, c_s1, SCM_F_WIND_EXPLICITLY); + + c_s2 = scm_to_string (s2); + scm_frame_unwind_handler (free, c_s2, SCM_F_WIND_EXPLICITLY); + + c_res = foo (c_s1, c_s2); + if (c_res == NULL) + scm_memory_error ("foo"); + + scm_frame_end (); + + return scm_take0str (res); +@} +@end example + +@deftp {C Type} scm_t_frame_flags +This is an enumeration of several flags that modify the behavior of +@code{scm_begin_frame}. The flags are listed in the following table. + +@table @code +@item SCM_F_FRAME_REWINDABLE +The frame is @dfn{rewindable}. This means that it can be reentered +non-locally (via the invokation of a continuation). The default is that +a frame can not be reentered non-locally. +@end table + +@end deftp + +@deftypefn {C Function} void scm_frame_begin (scm_t_frame_flags flags) +The function @code{scm_begin_frame} starts a new frame and makes it the +`current' one. + +The @var{flags} argument determines the default behavior of the frame. +For normal frames, use 0. This will result in a frame that can not be +reentered with a captured continuation. When you are prepared to handle +reentries, include @code{SCM_F_FRAME_REWINDABLE} in @var{flags}. + +Being prepared for reentry means that the effects of unwind handlers +can be undone on reentry. In the example above, we want to prevent a +memory leak on non-local exit and thus register an unwind handler that +frees the memory. But once the memory is freed, we can not get it +back on reentry. Thus reentry can not be allowed. + +The consequence is that continuations become less useful when +non-reenterable frames are captured, but you don't need to worry about +that too much. + +The frame is ended either implicitly when a non-local exit happens, or +explicitly with @code{scm_end_frame}. You must make sure that a frame +is indeed ended properly. If you fail to call @code{scm_end_frame} +for each @code{scm_begin_frame}, the behavior is undefined. +@end deftypefn + +@deftypefn {C Function} void scm_frame_end () +End the current frame explicitly and make the previous frame current. +@end deftypefn + +@deftp {C Type} scm_t_wind_flags +This is an enumeration of several flags that modify the behavior of +@code{scm_on_unwind_handler} and @code{scm_on_rewind_handler}. The +flags are listed in the following table. + +@table @code +@item SCM_F_WIND_EXPLICITLY +@vindex SCM_F_WIND_EXPLICITLY +The registered action is also carried out when the frame is entered or +left locally. +@end table +@end deftp + +@deftypefn {C Function} void scm_frame_unwind_handler (void (*func)(void *), void *data, scm_t_wind_flags flags) +@deftypefnx {C Function} void scm_frame_unwind_handler_with_scm (void (*func)(SCM), SCM data, scm_t_wind_flags flags) +Arranges for @var{func} to be called with @var{data} as its arguments +when the current frame ends implicitly. If @var{flags} contains +@code{SCM_F_WIND_EXPLICITLY}, @var{func} is also called when the frame +ends explicitly with @code{scm_frame_end}. + +The function @code{scm_frame_unwind_handler_with_scm} takes care that +@var{data} is protected from garbage collection. +@end deftypefn + +@deftypefn {C Function} void scm_frame_rewind_handler (void (*func)(void *), void *data, scm_t_wind_flags flags) +@deftypefnx {C Function} void scm_frame_rewind_handler_with_scm (void (*func)(SCM), SCM data, scm_t_wind_flags flags) +Arrange for @var{func} to be called with @var{data} as its argument when +the current frame is restarted by rewinding the stack. When @var{flags} +contains @code{SCM_F_WIND_EXPLICITLY}, @var{func} is called immediately +as well. + +The function @code{scm_frame_rewind_handler_with_scm} takes care that +@var{data} is protected from garbage collection. +@end deftypefn + + +@node Handling Errors +@subsection How to Handle Errors + +Error handling is based on @code{catch} and @code{throw}. Errors are +always thrown with a @var{key} and four arguments: + +@itemize @bullet +@item +@var{key}: a symbol which indicates the type of error. The symbols used +by libguile are listed below. + +@item +@var{subr}: the name of the procedure from which the error is thrown, or +@code{#f}. + +@item +@var{message}: a string (possibly language and system dependent) +describing the error. The tokens @code{~A} and @code{~S} can be +embedded within the message: they will be replaced with members of the +@var{args} list when the message is printed. @code{~A} indicates an +argument printed using @code{display}, while @code{~S} indicates an +argument printed using @code{write}. @var{message} can also be +@code{#f}, to allow it to be derived from the @var{key} by the error +handler (may be useful if the @var{key} is to be thrown from both C and +Scheme). + +@item +@var{args}: a list of arguments to be used to expand @code{~A} and +@code{~S} tokens in @var{message}. Can also be @code{#f} if no +arguments are required. + +@item +@var{rest}: a list of any additional objects required. e.g., when the +key is @code{'system-error}, this contains the C errno value. Can also +be @code{#f} if no additional objects are required. +@end itemize + +In addition to @code{catch} and @code{throw}, the following Scheme +facilities are available: + +@deffn {Scheme Procedure} display-error stack port subr message args rest +@deffnx {C Function} scm_display_error (stack, port, subr, message, args, rest) +Display an error message to the output port @var{port}. +@var{stack} is the saved stack for the error, @var{subr} is +the name of the procedure in which the error occurred and +@var{message} is the actual error message, which may contain +formatting instructions. These will format the arguments in +the list @var{args} accordingly. @var{rest} is currently +ignored. +@end deffn + +The following are the error keys defined by libguile and the situations +in which they are used: + +@itemize @bullet +@item +@cindex @code{error-signal} +@code{error-signal}: thrown after receiving an unhandled fatal signal +such as SIGSEGV, SIGBUS, SIGFPE etc. The @var{rest} argument in the throw +contains the coded signal number (at present this is not the same as the +usual Unix signal number). + +@item +@cindex @code{system-error} +@code{system-error}: thrown after the operating system indicates an +error condition. The @var{rest} argument in the throw contains the +errno value. + +@item +@cindex @code{numerical-overflow} +@code{numerical-overflow}: numerical overflow. + +@item +@cindex @code{out-of-range} +@code{out-of-range}: the arguments to a procedure do not fall within the +accepted domain. + +@item +@cindex @code{wrong-type-arg} +@code{wrong-type-arg}: an argument to a procedure has the wrong type. + +@item +@cindex @code{wrong-number-of-args} +@code{wrong-number-of-args}: a procedure was called with the wrong number +of arguments. + +@item +@cindex @code{memory-allocation-error} +@code{memory-allocation-error}: memory allocation error. + +@item +@cindex @code{stack-overflow} +@code{stack-overflow}: stack overflow error. + +@item +@cindex @code{regular-expression-syntax} +@code{regular-expression-syntax}: errors generated by the regular +expression library. + +@item +@cindex @code{misc-error} +@code{misc-error}: other errors. +@end itemize + + +@subsubsection C Support + +In the following C functions, @var{SUBR} and @var{MESSAGE} parameters +can be @code{NULL} to give the effect of @code{#f} described above. + +@deftypefn {C Function} SCM scm_error (SCM @var{key}, char *@var{subr}, char *@var{message}, SCM @var{args}, SCM @var{rest}) +Throw an error, as per @code{scm-error} above. +@end deftypefn + +@deftypefn {C Function} void scm_syserror (char *@var{subr}) +@deftypefnx {C Function} void scm_syserror_msg (char *@var{subr}, char *@var{message}, SCM @var{args}) +Throw an error with key @code{system-error} and supply @code{errno} in +the @var{rest} argument. For @code{scm_syserror} the message is +generated using @code{strerror}. + +Care should be taken that any code in between the failing operation +and the call to these routines doesn't change @code{errno}. +@end deftypefn + +@deftypefn {C Function} void scm_num_overflow (char *@var{subr}) +@deftypefnx {C Function} void scm_out_of_range (char *@var{subr}, SCM @var{bad_value}) +@deftypefnx {C Function} void scm_wrong_num_args (SCM @var{proc}) +@deftypefnx {C Function} void scm_wrong_type_arg (char *@var{subr}, int @var{argnum}, SCM @var{bad_value}) +@deftypefnx {C Function} void scm_memory_error (char *@var{subr}) +Throw an error with the various keys described above. + +For @code{scm_wrong_num_args}, @var{proc} should be a Scheme symbol +which is the name of the procedure incorrectly invoked. +@end deftypefn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi new file mode 100755 index 000000000..e1fe65e8a --- /dev/null +++ b/doc/ref/api-data.texi @@ -0,0 +1,3591 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Simple Data Types +@section Simple Generic Data Types + +This chapter describes those of Guile's simple data types which are +primarily used for their role as items of generic data. By +@dfn{simple} we mean data types that are not primarily used as +containers to hold other data --- i.e.@: pairs, lists, vectors and so on. +For the documentation of such @dfn{compound} data types, see +@ref{Compound Data Types}. + +@c One of the great strengths of Scheme is that there is no straightforward +@c distinction between ``data'' and ``functionality''. For example, +@c Guile's support for dynamic linking could be described: + +@c @itemize @bullet +@c @item +@c either in a ``data-centric'' way, as the behaviour and properties of the +@c ``dynamically linked object'' data type, and the operations that may be +@c applied to instances of this type + +@c @item +@c or in a ``functionality-centric'' way, as the set of procedures that +@c constitute Guile's support for dynamic linking, in the context of the +@c module system. +@c @end itemize + +@c The contents of this chapter are, therefore, a matter of judgment. By +@c @dfn{generic}, we mean to select those data types whose typical use as +@c @emph{data} in a wide variety of programming contexts is more important +@c than their use in the implementation of a particular piece of +@c @emph{functionality}. The last section of this chapter provides +@c references for all the data types that are documented not here but in a +@c ``functionality-centric'' way elsewhere in the manual. + +@menu +* Booleans:: True/false values. +* Numbers:: Numerical data types. +* Characters:: New character names. +* Strings:: Special things about strings. +* Regular Expressions:: Pattern matching and substitution. +* Symbols:: Symbols. +* Keywords:: Self-quoting, customizable display keywords. +* Other Types:: "Functionality-centric" data types. +@end menu + + +@node Booleans +@subsection Booleans +@tpindex Booleans + +The two boolean values are @code{#t} for true and @code{#f} for false. + +Boolean values are returned by predicate procedures, such as the general +equality predicates @code{eq?}, @code{eqv?} and @code{equal?} +(@pxref{Equality}) and numerical and string comparison operators like +@code{string=?} (@pxref{String Comparison}) and @code{<=} +(@pxref{Comparison}). + +@lisp +(<= 3 8) +@result{} #t + +(<= 3 -3) +@result{} #f + +(equal? "house" "houses") +@result{} #f + +(eq? #f #f) +@result{} +#t +@end lisp + +In test condition contexts like @code{if} and @code{cond} (@pxref{if +cond case}), where a group of subexpressions will be evaluated only if a +@var{condition} expression evaluates to ``true'', ``true'' means any +value at all except @code{#f}. + +@lisp +(if #t "yes" "no") +@result{} "yes" + +(if 0 "yes" "no") +@result{} "yes" + +(if #f "yes" "no") +@result{} "no" +@end lisp + +A result of this asymmetry is that typical Scheme source code more often +uses @code{#f} explicitly than @code{#t}: @code{#f} is necessary to +represent an @code{if} or @code{cond} false value, whereas @code{#t} is +not necessary to represent an @code{if} or @code{cond} true value. + +It is important to note that @code{#f} is @strong{not} equivalent to any +other Scheme value. In particular, @code{#f} is not the same as the +number 0 (like in C and C++), and not the same as the ``empty list'' +(like in some Lisp dialects). + +In C, the two Scheme boolean values are available as the two constants +@code{SCM_BOOL_T} for @code{#t} and @code{SCM_BOOL_F} for @code{#f}. +Care must be taken with the false value @code{SCM_BOOL_F}: it is not +false when used in C conditionals. In order to test for it, use +@code{scm_is_false} or @code{scm_is_true}. + +@rnindex not +@deffn {Scheme Procedure} not x +@deffnx {C Function} scm_not (x) +Return @code{#t} if @var{x} is @code{#f}, else return @code{#f}. +@end deffn + +@rnindex boolean? +@deffn {Scheme Procedure} boolean? obj +@deffnx {C Function} scm_boolean_p (obj) +Return @code{#t} if @var{obj} is either @code{#t} or @code{#f}, else +return @code{#f}. +@end deffn + +@deftypevr {C Macro} SCM SCM_BOOL_T +The @code{SCM} representation of the Scheme object @code{#t}. +@end deftypevr + +@deftypevr {C Macro} SCM SCM_BOOL_F +The @code{SCM} representation of the Scheme object @code{#f}. +@end deftypevr + +@deftypefn {C Function} int scm_is_true (SCM obj) +Return @code{0} if @var{obj} is @code{#f}, else return @code{1}. +@end deftypefn + +@deftypefn {C Function} int scm_is_false (SCM obj) +Return @code{1} if @var{obj} is @code{#f}, else return @code{0}. +@end deftypefn + +@deftypefn {C Function} int scm_is_bool (SCM obj) +Return @code{1} if @var{obj} is either @code{#t} or @code{#f}, else +return @code{0}. +@end deftypefn + +@deftypefn {C Function} SCM scm_from_bool (int val) +Return @code{#f} if @var{val} is @code{0}, else return @code{#t}. +@end deftypefn + +@deftypefn {C Function} int scm_to_bool (SCM val) +Return @code{1} if @var{val} is @code{SCM_BOOL_T}, return @code{0} +when @var{val} is @code{SCM_BOOL_F}, else signal a `wrong type' error. + +You should probably use @code{scm_is_true} instead of this function +when you just want to test a @code{SCM} value for trueness. +@end deftypefn + +@node Numbers +@subsection Numerical data types +@tpindex Numbers + +Guile supports a rich ``tower'' of numerical types --- integer, +rational, real and complex --- and provides an extensive set of +mathematical and scientific functions for operating on numerical +data. This section of the manual documents those types and functions. + +You may also find it illuminating to read R5RS's presentation of numbers +in Scheme, which is particularly clear and accessible: see +@ref{Numbers,,,r5rs,R5RS}. + +@menu +* Numerical Tower:: Scheme's numerical "tower". +* Integers:: Whole numbers. +* Reals and Rationals:: Real and rational numbers. +* Complex Numbers:: Complex numbers. +* Exactness:: Exactness and inexactness. +* Number Syntax:: Read syntax for numerical data. +* Integer Operations:: Operations on integer values. +* Comparison:: Comparison predicates. +* Conversion:: Converting numbers to and from strings. +* Complex:: Complex number operations. +* Arithmetic:: Arithmetic functions. +* Scientific:: Scientific functions. +* Primitive Numerics:: Primitive numeric functions. +* Bitwise Operations:: Logical AND, OR, NOT, and so on. +* Random:: Random number generation. +@end menu + + +@node Numerical Tower +@subsubsection Scheme's Numerical ``Tower'' +@rnindex number? + +Scheme's numerical ``tower'' consists of the following categories of +numbers: + +@table @dfn +@item integers +Whole numbers, positive or negative; e.g.@: --5, 0, 18. + +@item rationals +The set of numbers that can be expressed as @math{@var{p}/@var{q}} +where @var{p} and @var{q} are integers; e.g.@: @math{9/16} works, but +pi (an irrational number) doesn't. These include integers +(@math{@var{n}/1}). + +@item real numbers +The set of numbers that describes all possible positions along a +one-dimensional line. This includes rationals as well as irrational +numbers. + +@item complex numbers +The set of numbers that describes all possible positions in a two +dimensional space. This includes real as well as imaginary numbers +(@math{@var{a}+@var{b}i}, where @var{a} is the @dfn{real part}, +@var{b} is the @dfn{imaginary part}, and @math{i} is the square root of +@minus{}1.) +@end table + +It is called a tower because each category ``sits on'' the one that +follows it, in the sense that every integer is also a rational, every +rational is also real, and every real number is also a complex number +(but with zero imaginary part). + +In addition to the classification into integers, rationals, reals and +complex numbers, Scheme also distinguishes between whether a number is +represented exactly or not. For example, the result of +@m{2\sin(\pi/4),sin(pi/4)} is exactly @m{\sqrt{2},2^(1/2)} but Guile +can neither represent @m{\pi/4,pi/4} nor @m{\sqrt{2},2^(1/2)} exactly. +Instead, it stores an inexact approximation, using the C type +@code{double}. + +Guile can represent exact rationals of any magnitude, inexact +rationals that fit into a C @code{double}, and inexact complex numbers +with @code{double} real and imaginary parts. + +The @code{number?} predicate may be applied to any Scheme value to +discover whether the value is any of the supported numerical types. + +@deffn {Scheme Procedure} number? obj +@deffnx {C Function} scm_number_p (obj) +Return @code{#t} if @var{obj} is any kind of number, else @code{#f}. +@end deffn + +For example: + +@lisp +(number? 3) +@result{} #t + +(number? "hello there!") +@result{} #f + +(define pi 3.141592654) +(number? pi) +@result{} #t +@end lisp + +The next few subsections document each of Guile's numerical data types +in detail. + +@node Integers +@subsubsection Integers + +@tpindex Integer numbers + +@rnindex integer? + +Integers are whole numbers, that is numbers with no fractional part, +such as 2, 83, and @minus{}3789. + +Integers in Guile can be arbitrarily big, as shown by the following +example. + +@lisp +(define (factorial n) + (let loop ((n n) (product 1)) + (if (= n 0) + product + (loop (- n 1) (* product n))))) + +(factorial 3) +@result{} 6 + +(factorial 20) +@result{} 2432902008176640000 + +(- (factorial 45)) +@result{} -119622220865480194561963161495657715064383733760000000000 +@end lisp + +Readers whose background is in programming languages where integers are +limited by the need to fit into just 4 or 8 bytes of memory may find +this surprising, or suspect that Guile's representation of integers is +inefficient. In fact, Guile achieves a near optimal balance of +convenience and efficiency by using the host computer's native +representation of integers where possible, and a more general +representation where the required number does not fit in the native +form. Conversion between these two representations is automatic and +completely invisible to the Scheme level programmer. + +The infinities @samp{+inf.0} and @samp{-inf.0} are considered to be +inexact integers. They are explained in detail in the next section, +together with reals and rationals. + +C has a host of different integer types, and Guile offers a host of +functions to convert between them and the @code{SCM} representation. +For example, a C @code{int} can be handled with @code{scm_to_int} and +@code{scm_from_int}. Guile also defines a few C integer types of its +own, to help with differences between systems. + +C integer types that are not covered can be handled with the generic +@code{scm_to_signed_integer} and @code{scm_from_signed_integer} for +signed types, or with @code{scm_to_unsigned_integer} and +@code{scm_from_unsigned_integer} for unsigned types. + +Scheme integers can be exact and inexact. For example, a number +written as @code{3.0} with an explicit decimal-point is inexact, but +it is also an integer. The functions @code{integer?} and +@code{scm_is_integer} report true for such a number, but the functions +@code{scm_is_signed_integer} and @code{scm_is_unsigned_integer} only +allow exact integers and thus report false. Likewise, the conversion +functions like @code{scm_to_signed_integer} only accept exact +integers. + +The motivation for this behavior is that the inexactness of a number +should not be lost silently. If you want to allow inexact integers, +you can explicitely insert a call to @code{inexact->exact} or to its C +equivalent @code{scm_inexact_to_exact}. (Only inexact integers will +be converted by this call into exact integers; inexact non-integers +will become exact fractions.) + +@deffn {Scheme Procedure} integer? x +@deffnx {C Function} scm_integer_p (x) +Return @code{#t} if @var{x} is an exactor inexact integer number, else +@code{#f}. + +@lisp +(integer? 487) +@result{} #t + +(integer? 3.0) +@result{} #t + +(integer? -3.4) +@result{} #f + +(integer? +inf.0) +@result{} #t +@end lisp +@end deffn + +@deftypefn {C Function} int scm_is_integer (SCM x) +This is equivalent to @code{scm_is_true (scm_integer_p (x))}. +@end deftypefn + +@defvr {C Type} scm_t_int8 +@defvrx {C Type} scm_t_uint8 +@defvrx {C Type} scm_t_int16 +@defvrx {C Type} scm_t_uint16 +@defvrx {C Type} scm_t_int32 +@defvrx {C Type} scm_t_uint32 +@defvrx {C Type} scm_t_int64 +@defvrx {C Type} scm_t_uint64 +@defvrx {C Type} scm_t_intmax +@defvrx {C Type} scm_t_uintmax +The C types are equivalent to the corresponding ISO C types but are +defined on all platforms, with the exception of @code{scm_t_int64} and +@code{scm_t_uint64}, which are only defined when a 64-bit type is +available. For example, @code{scm_t_int8} is equivalent to +@code{int8_t}. + +You can regard these definitions as a stop-gap measure until all +platforms provide these types. If you know that all the platforms +that you are interested in already provide these types, it is better +to use them directly instead of the types provided by Guile. +@end defvr + +@deftypefn {C Function} int scm_is_signed_integer (SCM x, scm_t_intmax min, scm_t_intmax max) +@deftypefnx {C Function} int scm_is_unsigned_integer (SCM x, scm_t_uintmax min, scm_t_uintmax max) +Return @code{1} when @var{x} represents an exact integer that is +between @var{min} and @var{max}, inclusive. + +These functions can be used to check whether a @code{SCM} value will +fit into a given range, such as the range of a given C integer type. +If you just want to convert a @code{SCM} value to a given C integer +type, use one of the conversion functions directly. +@end deftypefn + +@deftypefn {C Function} scm_t_intmax scm_to_signed_integer (SCM x, scm_t_intmax min, scm_t_intmax max) +@deftypefnx {C Function} scm_t_uintmax scm_to_unsigned_integer (SCM x, scm_t_uintmax min, scm_t_uintmax max) +When @var{x} represents an exact integer that is between @var{min} and +@var{max} inclusive, return that integer. Else signal an error, +either a `wrong-type' error when @var{x} is not an exact integer, or +an `out-of-range' error when it doesn't fit the given range. +@end deftypefn + +@deftypefn {C Function} SCM scm_from_signed_integer (scm_t_intmax x) +@deftypefnx {C Function} SCM scm_from_unsigned_integer (scm_t_uintmax x) +Return the @code{SCM} value that represents the integer @var{x}. This +function will always succeed and will always return an exact number. +@end deftypefn + +@deftypefn {C Function} char scm_to_char (SCM x) +@deftypefnx {C Function} {signed char} scm_to_schar (SCM x) +@deftypefnx {C Function} {unsigned char} scm_to_uchar (SCM x) +@deftypefnx {C Function} short scm_to_short (SCM x) +@deftypefnx {C Function} {unsigned short} scm_to_ushort (SCM x) +@deftypefnx {C Function} int scm_to_int (SCM x) +@deftypefnx {C Function} {unsigned int} scm_to_uint (SCM x) +@deftypefnx {C Function} long scm_to_long (SCM x) +@deftypefnx {C Function} {unsigned long} scm_to_ulong (SCM x) +@deftypefnx {C Function} {long long} scm_to_long_long (SCM x) +@deftypefnx {C Function} {unsigned long long} scm_to_ulong_long (SCM x) +@deftypefnx {C Function} size_t scm_to_size_t (SCM x) +@deftypefnx {C Function} ssize_t scm_to_ssize_t (SCM x) +@deftypefnx {C Function} scm_t_int8 scm_to_int8 (SCM x) +@deftypefnx {C Function} scm_t_uint8 scm_to_uint8 (SCM x) +@deftypefnx {C Function} scm_t_int16 scm_to_int16 (SCM x) +@deftypefnx {C Function} scm_t_uint16 scm_to_uint16 (SCM x) +@deftypefnx {C Function} scm_t_int32 scm_to_int32 (SCM x) +@deftypefnx {C Function} scm_t_uint32 scm_to_uint32 (SCM x) +@deftypefnx {C Function} scm_t_int64 scm_to_int64 (SCM x) +@deftypefnx {C Function} scm_t_uint64 scm_to_uint64 (SCM x) +@deftypefnx {C Function} scm_t_intmax scm_to_intmax (SCM x) +@deftypefnx {C Function} scm_t_uintmax scm_to_uintmax (SCM x) +When @var{x} represents an exact integer that fits into the indicated +C type, return that integer. Else signal an error, either a +`wrong-type' error when @var{x} is not an exact integer, or an +`out-of-range' error when it doesn't fit the given range. + +The functions @code{scm_to_long_long}, @code{scm_to_ulong_long}, +@code{scm_to_int64}, and @code{scm_to_uint64} are only available when +the corresponding types are. +@end deftypefn + +@deftypefn {C Function} SCM scm_from_char (char x) +@deftypefnx {C Function} SCM scm_from_schar (signed char x) +@deftypefnx {C Function} SCM scm_from_uchar (unsigned char x) +@deftypefnx {C Function} SCM scm_from_short (short x) +@deftypefnx {C Function} SCM scm_from_ushort (unsigned short x) +@deftypefnx {C Function} SCM scm_from_int (int x) +@deftypefnx {C Function} SCM scm_from_uint (unsigned int x) +@deftypefnx {C Function} SCM scm_from_long (long x) +@deftypefnx {C Function} SCM scm_from_ulong (unsigned long x) +@deftypefnx {C Function} SCM scm_from_long_long (long long x) +@deftypefnx {C Function} SCM scm_from_ulong_long (unsigned long long x) +@deftypefnx {C Function} SCM scm_from_size_t (size_t x) +@deftypefnx {C Function} SCM scm_from_ssize_t (ssize_t x) +@deftypefnx {C Function} SCM scm_from_int8 (scm_t_int8 x) +@deftypefnx {C Function} SCM scm_from_uint8 (scm_t_uint8 x) +@deftypefnx {C Function} SCM scm_from_int16 (scm_t_int16 x) +@deftypefnx {C Function} SCM scm_from_uint16 (scm_t_uint16 x) +@deftypefnx {C Function} SCM scm_from_int32 (scm_t_int32 x) +@deftypefnx {C Function} SCM scm_from_uint32 (scm_t_uint32 x) +@deftypefnx {C Function} SCM scm_from_int64 (scm_t_int64 x) +@deftypefnx {C Function} SCM scm_from_uint64 (scm_t_uint64 x) +@deftypefnx {C Function} SCM scm_from_intmax (scm_t_intmax x) +@deftypefnx {C Function} SCM scm_from_uintmax (scm_t_uintmax x) +Return the @code{SCM} value that represents the integer @var{x}. +These functions will always succeed and will always return an exact +number. +@end deftypefn + +@node Reals and Rationals +@subsubsection Real and Rational Numbers +@tpindex Real numbers +@tpindex Rational numbers + +@rnindex real? +@rnindex rational? + +Mathematically, the real numbers are the set of numbers that describe +all possible points along a continuous, infinite, one-dimensional line. +The rational numbers are the set of all numbers that can be written as +fractions @var{p}/@var{q}, where @var{p} and @var{q} are integers. +All rational numbers are also real, but there are real numbers that +are not rational, for example the square root of 2, and pi. + +Guile can represent both exact and inexact rational numbers, but it +can not represent irrational numbers. Exact rationals are represented +by storing the numerator and denominator as two exact integers. +Inexact rationals are stored as floating point numbers using the C +type @code{double}. + +Exact rationals are written as a fraction of integers. There must be +no whitespace around the slash: + +@lisp +1/2 +-22/7 +@end lisp + +Even though the actual encoding of inexact rationals is in binary, it +may be helpful to think of it as a decimal number with a limited +number of significant figures and a decimal point somewhere, since +this corresponds to the standard notation for non-whole numbers. For +example: + +@lisp +0.34 +-0.00000142857931198 +-5648394822220000000000.0 +4.0 +@end lisp + +The limited precision of Guile's encoding means that any ``real'' number +in Guile can be written in a rational form, by multiplying and then dividing +by sufficient powers of 10 (or in fact, 2). For example, +@samp{-0.00000142857931198} is the same as @minus{}142857931198 divided by +100000000000000000. In Guile's current incarnation, therefore, the +@code{rational?} and @code{real?} predicates are equivalent. + + +Dividing by an exact zero leads to a error message, as one might +expect. However, dividing by an inexact zero does not produce an +error. Instead, the result of the division is either plus or minus +infinity, depending on the sign of the divided number. + +The infinities are written @samp{+inf.0} and @samp{-inf.0}, +respectivly. This syntax is also recognized by @code{read} as an +extension to the usual Scheme syntax. + +Dividing zero by zero yields something that is not a number at all: +@samp{+nan.0}. This is the special `not a number' value. + +On platforms that follow @acronym{IEEE} 754 for their floating point +arithmetic, the @samp{+inf.0}, @samp{-inf.0}, and @samp{+nan.0} values +are implemented using the corresponding @acronym{IEEE} 754 values. +They behave in arithmetic operations like @acronym{IEEE} 754 describes +it, i.e., @code{(= +nan.0 +nan.0)} @result{} @code{#f}. + +The infinities are inexact integers and are considered to be both even +and odd. While @samp{+nan.0} is not @code{=} to itself, it is +@code{eqv?} to itself. + +To test for the special values, use the functions @code{inf?} and +@code{nan?}. + +@deffn {Scheme Procedure} real? obj +@deffnx {C Function} scm_real_p (obj) +Return @code{#t} if @var{obj} is a real number, else @code{#f}. Note +that the sets of integer and rational values form subsets of the set +of real numbers, so the predicate will also be fulfilled if @var{obj} +is an integer number or a rational number. +@end deffn + +@deffn {Scheme Procedure} rational? x +@deffnx {C Function} scm_rational_p (x) +Return @code{#t} if @var{x} is a rational number, @code{#f} otherwise. +Note that the set of integer values forms a subset of the set of +rational numbers, i. e. the predicate will also be fulfilled if +@var{x} is an integer number. + +Since Guile can not represent irrational numbers, every number +satisfying @code{real?} also satisfies @code{rational?} in Guile. +@end deffn + +@deffn {Scheme Procedure} rationalize x eps +@deffnx {C Function} scm_rationalize (x, eps) +Returns the @emph{simplest} rational number differing +from @var{x} by no more than @var{eps}. + +As required by @acronym{R5RS}, @code{rationalize} only returns an +exact result when both its arguments are exact. Thus, you might need +to use @code{inexact->exact} on the arguments. + +@lisp +(rationalize (inexact->exact 1.2) 1/100) +@result{} 6/5 +@end lisp + +@end deffn + +@deffn {Scheme Procedure} inf? x +Return @code{#t} if @var{x} is either @samp{+inf.0} or @samp{-inf.0}, +@code{#f} otherwise. +@end deffn + +@deffn {Scheme Procedure} nan? x +Return @code{#t} if @var{x} is @samp{+nan.0}, @code{#f} otherwise. +@end deffn + +@node Complex Numbers +@subsubsection Complex Numbers +@tpindex Complex numbers + +@rnindex complex? + +Complex numbers are the set of numbers that describe all possible points +in a two-dimensional space. The two coordinates of a particular point +in this space are known as the @dfn{real} and @dfn{imaginary} parts of +the complex number that describes that point. + +In Guile, complex numbers are written in rectangular form as the sum of +their real and imaginary parts, using the symbol @code{i} to indicate +the imaginary part. + +@lisp +3+4i +@result{} +3.0+4.0i + +(* 3-8i 2.3+0.3i) +@result{} +9.3-17.5i +@end lisp + +Guile represents a complex number with a non-zero imaginary part as a +pair of inexact rationals, so the real and imaginary parts of a +complex number have the same properties of inexactness and limited +precision as single inexact rational numbers. Guile can not represent +exact complex numbers with non-zero imaginary parts. + +@deffn {Scheme Procedure} complex? x +@deffnx {C Function} scm_number_p (x) +Return @code{#t} if @var{x} is a complex number, @code{#f} +otherwise. Note that the sets of real, rational and integer +values form subsets of the set of complex numbers, i. e. the +predicate will also be fulfilled if @var{x} is a real, +rational or integer number. +@end deffn + + +@node Exactness +@subsubsection Exact and Inexact Numbers +@tpindex Exact numbers +@tpindex Inexact numbers + +@rnindex exact? +@rnindex inexact? +@rnindex exact->inexact +@rnindex inexact->exact + +R5RS requires that a calculation involving inexact numbers always +produces an inexact result. To meet this requirement, Guile +distinguishes between an exact integer value such as @samp{5} and the +corresponding inexact real value which, to the limited precision +available, has no fractional part, and is printed as @samp{5.0}. Guile +will only convert the latter value to the former when forced to do so by +an invocation of the @code{inexact->exact} procedure. + +@deffn {Scheme Procedure} exact? z +@deffnx {C Function} scm_exact_p (z) +Return @code{#t} if the number @var{z} is exact, @code{#f} +otherwise. + +@lisp +(exact? 2) +@result{} #t + +(exact? 0.5) +@result{} #f + +(exact? (/ 2)) +@result{} #t +@end lisp + +@end deffn + +@deffn {Scheme Procedure} inexact? z +@deffnx {C Function} scm_inexact_p (z) +Return @code{#t} if the number @var{z} is inexact, @code{#f} +else. +@end deffn + +@deffn {Scheme Procedure} inexact->exact z +@deffnx {C Function} scm_inexact_to_exact (z) +Return an exact number that is numerically closest to @var{z}, when +there is one. For inexact rationals, Guile returns the exact rational +that is numerically equal to the inexact rational. Inexact complex +numbers with a non-zero imaginary part can not be made exact. + +@lisp +(inexact->exact 0.5) +@result{} 1/2 +@end lisp + +The following happens because 12/10 is not exactly representable as a +@code{double} (on most platforms). However, when reading a decimal +number that has been marked exact with the ``#e'' prefix, Guile is +able to represent it correctly. + +@lisp +(inexact->exact 1.2) +@result{} 5404319552844595/4503599627370496 + +#e1.2 +@result{} 6/5 +@end lisp + +@end deffn + +@c begin (texi-doc-string "guile" "exact->inexact") +@deffn {Scheme Procedure} exact->inexact z +@deffnx {C Function} scm_exact_to_inexact (z) +Convert the number @var{z} to its inexact representation. +@end deffn + + +@node Number Syntax +@subsubsection Read Syntax for Numerical Data + +The read syntax for integers is a string of digits, optionally +preceded by a minus or plus character, a code indicating the +base in which the integer is encoded, and a code indicating whether +the number is exact or inexact. The supported base codes are: + +@table @code +@item #b +@itemx #B +the integer is written in binary (base 2) + +@item #o +@itemx #O +the integer is written in octal (base 8) + +@item #d +@itemx #D +the integer is written in decimal (base 10) + +@item #x +@itemx #X +the integer is written in hexadecimal (base 16) +@end table + +If the base code is omitted, the integer is assumed to be decimal. The +following examples show how these base codes are used. + +@lisp +-13 +@result{} -13 + +#d-13 +@result{} -13 + +#x-13 +@result{} -19 + +#b+1101 +@result{} 13 + +#o377 +@result{} 255 +@end lisp + +The codes for indicating exactness (which can, incidentally, be applied +to all numerical values) are: + +@table @code +@item #e +@itemx #E +the number is exact + +@item #i +@itemx #I +the number is inexact. +@end table + +If the exactness indicator is omitted, the number is exact unless it +contains a radix point. Since Guile can not represent exact complex +numbers, an error is signalled when asking for them. + +@lisp +(exact? 1.2) +@result{} #f + +(exact? #e1.2) +@result{} #t + +(exact? #e+1i) +ERROR: Wrong type argument +@end lisp + +Guile also understands the syntax @samp{+inf.0} and @samp{-inf.0} for +plus and minus infinity, respectively. The value must be written +exactly as shown, that is, they always must have a sign and exactly +one zero digit after the decimal point. It also understands +@samp{+nan.0} and @samp{-nan.0} for the special `not-a-number' value. +The sign is ignored for `not-a-number' and the value is always printed +as @samp{+nan.0}. + +@node Integer Operations +@subsubsection Operations on Integer Values +@rnindex odd? +@rnindex even? +@rnindex quotient +@rnindex remainder +@rnindex modulo +@rnindex gcd +@rnindex lcm + +@deffn {Scheme Procedure} odd? n +@deffnx {C Function} scm_odd_p (n) +Return @code{#t} if @var{n} is an odd number, @code{#f} +otherwise. +@end deffn + +@deffn {Scheme Procedure} even? n +@deffnx {C Function} scm_even_p (n) +Return @code{#t} if @var{n} is an even number, @code{#f} +otherwise. +@end deffn + +@c begin (texi-doc-string "guile" "quotient") +@c begin (texi-doc-string "guile" "remainder") +@deffn {Scheme Procedure} quotient n d +@deffnx {Scheme Procedure} remainder n d +@deffnx {C Function} scm_quotient (n, d) +@deffnx {C Function} scm_remainder (n, d) +Return the quotient or remainder from @var{n} divided by @var{d}. The +quotient is rounded towards zero, and the remainder will have the same +sign as @var{n}. In all cases quotient and remainder satisfy +@math{@var{n} = @var{q}*@var{d} + @var{r}}. + +@lisp +(remainder 13 4) @result{} 1 +(remainder -13 4) @result{} -1 +@end lisp +@end deffn + +@c begin (texi-doc-string "guile" "modulo") +@deffn {Scheme Procedure} modulo n d +@deffnx {C Function} scm_modulo (n, d) +Return the remainder from @var{n} divided by @var{d}, with the same +sign as @var{d}. + +@lisp +(modulo 13 4) @result{} 1 +(modulo -13 4) @result{} 3 +(modulo 13 -4) @result{} -3 +(modulo -13 -4) @result{} -1 +@end lisp +@end deffn + +@c begin (texi-doc-string "guile" "gcd") +@deffn {Scheme Procedure} gcd +@deffnx {C Function} scm_gcd (x, y) +Return the greatest common divisor of all arguments. +If called without arguments, 0 is returned. + +The C function @code{scm_gcd} always takes two arguments, while the +Scheme function can take an arbitrary number. +@end deffn + +@c begin (texi-doc-string "guile" "lcm") +@deffn {Scheme Procedure} lcm +@deffnx {C Function} scm_lcm (x, y) +Return the least common multiple of the arguments. +If called without arguments, 1 is returned. + +The C function @code{scm_lcm} always takes two arguments, while the +Scheme function can take an arbitrary number. +@end deffn + + +@node Comparison +@subsubsection Comparison Predicates +@rnindex zero? +@rnindex positive? +@rnindex negative? + +The C comparison functions below always takes two arguments, while the +Scheme functions can take an arbitrary number. Also keep in mind that +the C functions return one of the Scheme boolean values +@code{SCM_BOOL_T} or @code{SCM_BOOL_F} which are both true as far as C +is concerned. Thus, always write @code{scm_is_true (scm_num_eq_p (x, +y))} when testing the two Scheme numbers @code{x} and @code{y} for +equality, for example. + +@c begin (texi-doc-string "guile" "=") +@deffn {Scheme Procedure} = +@deffnx {C Function} scm_num_eq_p (x, y) +Return @code{#t} if all parameters are numerically equal. +@end deffn + +@c begin (texi-doc-string "guile" "<") +@deffn {Scheme Procedure} < +@deffnx {C Function} scm_less_p (x, y) +Return @code{#t} if the list of parameters is monotonically +increasing. +@end deffn + +@c begin (texi-doc-string "guile" ">") +@deffn {Scheme Procedure} > +@deffnx {C Function} scm_gr_p (x, y) +Return @code{#t} if the list of parameters is monotonically +decreasing. +@end deffn + +@c begin (texi-doc-string "guile" "<=") +@deffn {Scheme Procedure} <= +@deffnx {C Function} scm_leq_p (x, y) +Return @code{#t} if the list of parameters is monotonically +non-decreasing. +@end deffn + +@c begin (texi-doc-string "guile" ">=") +@deffn {Scheme Procedure} >= +@deffnx {C Function} scm_geq_p (x, y) +Return @code{#t} if the list of parameters is monotonically +non-increasing. +@end deffn + +@c begin (texi-doc-string "guile" "zero?") +@deffn {Scheme Procedure} zero? z +@deffnx {C Function} scm_zero_p (z) +Return @code{#t} if @var{z} is an exact or inexact number equal to +zero. +@end deffn + +@c begin (texi-doc-string "guile" "positive?") +@deffn {Scheme Procedure} positive? x +@deffnx {C Function} scm_positive_p (x) +Return @code{#t} if @var{x} is an exact or inexact number greater than +zero. +@end deffn + +@c begin (texi-doc-string "guile" "negative?") +@deffn {Scheme Procedure} negative? x +@deffnx {C Function} scm_negative_p (x) +Return @code{#t} if @var{x} is an exact or inexact number less than +zero. +@end deffn + + +@node Conversion +@subsubsection Converting Numbers To and From Strings +@rnindex number->string +@rnindex string->number + +@deffn {Scheme Procedure} number->string n [radix] +@deffnx {C Function} scm_number_to_string (n, radix) +Return a string holding the external representation of the +number @var{n} in the given @var{radix}. If @var{n} is +inexact, a radix of 10 will be used. +@end deffn + +@deffn {Scheme Procedure} string->number string [radix] +@deffnx {C Function} scm_string_to_number (string, radix) +Return a number of the maximally precise representation +expressed by the given @var{string}. @var{radix} must be an +exact integer, either 2, 8, 10, or 16. If supplied, @var{radix} +is a default radix that may be overridden by an explicit radix +prefix in @var{string} (e.g. "#o177"). If @var{radix} is not +supplied, then the default radix is 10. If string is not a +syntactically valid notation for a number, then +@code{string->number} returns @code{#f}. +@end deffn + + +@node Complex +@subsubsection Complex Number Operations +@rnindex make-rectangular +@rnindex make-polar +@rnindex real-part +@rnindex imag-part +@rnindex magnitude +@rnindex angle + +@deffn {Scheme Procedure} make-rectangular real imaginary +@deffnx {C Function} scm_make_rectangular (real, imaginary) +Return a complex number constructed of the given @var{real} and +@var{imaginary} parts. +@end deffn + +@deffn {Scheme Procedure} make-polar x y +@deffnx {C Function} scm_make_polar (x, y) +Return the complex number @var{x} * e^(i * @var{y}). +@end deffn + +@c begin (texi-doc-string "guile" "real-part") +@deffn {Scheme Procedure} real-part z +@deffnx {C Function} scm_real_part (z) +Return the real part of the number @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "imag-part") +@deffn {Scheme Procedure} imag-part z +@deffnx {C Function} scm_imag_part (z) +Return the imaginary part of the number @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "magnitude") +@deffn {Scheme Procedure} magnitude z +@deffnx {C Function} scm_magnitude (z) +Return the magnitude of the number @var{z}. This is the same as +@code{abs} for real arguments, but also allows complex numbers. +@end deffn + +@c begin (texi-doc-string "guile" "angle") +@deffn {Scheme Procedure} angle z +@deffnx {C Function} scm_angle (z) +Return the angle of the complex number @var{z}. +@end deffn + + +@node Arithmetic +@subsubsection Arithmetic Functions +@rnindex max +@rnindex min +@rnindex + +@rnindex * +@rnindex - +@rnindex / +@rnindex abs +@rnindex floor +@rnindex ceiling +@rnindex truncate +@rnindex round + +The C arithmetic functions below always takes two arguments, while the +Scheme functions can take an arbitrary number. When you need to +invoke them with just one argument, for example to compute the +equivalent od @code{(- x)}, pass @code{SCM_UNDEFINED} as the second +one: @code{scm_difference (x, SCM_UNDEFINED)}. + +@c begin (texi-doc-string "guile" "+") +@deffn {Scheme Procedure} + z1 @dots{} +@deffnx {C Function} scm_sum (z1, z2) +Return the sum of all parameter values. Return 0 if called without any +parameters. +@end deffn + +@c begin (texi-doc-string "guile" "-") +@deffn {Scheme Procedure} - z1 z2 @dots{} +@deffnx {C Function} scm_difference (z1, z2) +If called with one argument @var{z1}, -@var{z1} is returned. Otherwise +the sum of all but the first argument are subtracted from the first +argument. +@end deffn + +@c begin (texi-doc-string "guile" "*") +@deffn {Scheme Procedure} * z1 @dots{} +@deffnx {C Function} scm_product (z1, z2) +Return the product of all arguments. If called without arguments, 1 is +returned. +@end deffn + +@c begin (texi-doc-string "guile" "/") +@deffn {Scheme Procedure} / z1 z2 @dots{} +@deffnx {C Function} scm_divide (z1, z2) +Divide the first argument by the product of the remaining arguments. If +called with one argument @var{z1}, 1/@var{z1} is returned. +@end deffn + +@c begin (texi-doc-string "guile" "abs") +@deffn {Scheme Procedure} abs x +@deffnx {C Function} scm_abs (x) +Return the absolute value of @var{x}. + +@var{x} must be a number with zero imaginary part. To calculate the +magnitude of a complex number, use @code{magnitude} instead. +@end deffn + +@c begin (texi-doc-string "guile" "max") +@deffn {Scheme Procedure} max x1 x2 @dots{} +@deffnx {C Function} scm_max (x1, x2) +Return the maximum of all parameter values. +@end deffn + +@c begin (texi-doc-string "guile" "min") +@deffn {Scheme Procedure} min x1 x2 @dots{} +@deffnx {C Function} scm_min (x1, x2) +Return the minimum of all parameter values. +@end deffn + +@c begin (texi-doc-string "guile" "truncate") +@deffn {Scheme Procedure} truncate +@deffnx {C Function} scm_truncate_number (x) +Round the inexact number @var{x} towards zero. +@end deffn + +@c begin (texi-doc-string "guile" "round") +@deffn {Scheme Procedure} round x +@deffnx {C Function} scm_round_number (x) +Round the inexact number @var{x} to the nearest integer. When exactly +halfway between two integers, round to the even one. +@end deffn + +@c begin (texi-doc-string "guile" "floor") +@deffn {Scheme Procedure} floor x +@deffnx {C Function} scm_floor (x) +Round the number @var{x} towards minus infinity. +@end deffn + +@c begin (texi-doc-string "guile" "ceiling") +@deffn {Scheme Procedure} ceiling x +@deffnx {C Function} scm_ceiling (x) +Round the number @var{x} towards infinity. +@end deffn + + +@node Scientific +@subsubsection Scientific Functions + +The following procedures accept any kind of number as arguments, +including complex numbers. + +@rnindex sqrt +@c begin (texi-doc-string "guile" "sqrt") +@deffn {Scheme Procedure} sqrt z +Return the square root of @var{z}. +@end deffn + +@rnindex expt +@c begin (texi-doc-string "guile" "expt") +@deffn {Scheme Procedure} expt z1 z2 +Return @var{z1} raised to the power of @var{z2}. +@end deffn + +@rnindex sin +@c begin (texi-doc-string "guile" "sin") +@deffn {Scheme Procedure} sin z +Return the sine of @var{z}. +@end deffn + +@rnindex cos +@c begin (texi-doc-string "guile" "cos") +@deffn {Scheme Procedure} cos z +Return the cosine of @var{z}. +@end deffn + +@rnindex tan +@c begin (texi-doc-string "guile" "tan") +@deffn {Scheme Procedure} tan z +Return the tangent of @var{z}. +@end deffn + +@rnindex asin +@c begin (texi-doc-string "guile" "asin") +@deffn {Scheme Procedure} asin z +Return the arcsine of @var{z}. +@end deffn + +@rnindex acos +@c begin (texi-doc-string "guile" "acos") +@deffn {Scheme Procedure} acos z +Return the arccosine of @var{z}. +@end deffn + +@rnindex atan +@c begin (texi-doc-string "guile" "atan") +@deffn {Scheme Procedure} atan z +@deffnx {Scheme Procedure} atan y x +Return the arctangent of @var{z}, or of @math{@var{y}/@var{x}}. +@end deffn + +@rnindex exp +@c begin (texi-doc-string "guile" "exp") +@deffn {Scheme Procedure} exp z +Return e to the power of @var{z}, where e is the base of natural +logarithms (2.71828@dots{}). +@end deffn + +@rnindex log +@c begin (texi-doc-string "guile" "log") +@deffn {Scheme Procedure} log z +Return the natural logarithm of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "log10") +@deffn {Scheme Procedure} log10 z +Return the base 10 logarithm of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "sinh") +@deffn {Scheme Procedure} sinh z +Return the hyperbolic sine of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "cosh") +@deffn {Scheme Procedure} cosh z +Return the hyperbolic cosine of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "tanh") +@deffn {Scheme Procedure} tanh z +Return the hyperbolic tangent of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "asinh") +@deffn {Scheme Procedure} asinh z +Return the hyperbolic arcsine of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "acosh") +@deffn {Scheme Procedure} acosh z +Return the hyperbolic arccosine of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "atanh") +@deffn {Scheme Procedure} atanh z +Return the hyperbolic arctangent of @var{z}. +@end deffn + + +@node Primitive Numerics +@subsubsection Primitive Numeric Functions + +Many of Guile's numeric procedures which accept any kind of numbers as +arguments, including complex numbers, are implemented as Scheme +procedures that use the following real number-based primitives. These +primitives signal an error if they are called with complex arguments. + +@c begin (texi-doc-string "guile" "$abs") +@deffn {Scheme Procedure} $abs x +Return the absolute value of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$sqrt") +@deffn {Scheme Procedure} $sqrt x +Return the square root of @var{x}. +@end deffn + +@deffn {Scheme Procedure} $expt x y +@deffnx {C Function} scm_sys_expt (x, y) +Return @var{x} raised to the power of @var{y}. This +procedure does not accept complex arguments. +@end deffn + +@c begin (texi-doc-string "guile" "$sin") +@deffn {Scheme Procedure} $sin x +Return the sine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$cos") +@deffn {Scheme Procedure} $cos x +Return the cosine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$tan") +@deffn {Scheme Procedure} $tan x +Return the tangent of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$asin") +@deffn {Scheme Procedure} $asin x +Return the arcsine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$acos") +@deffn {Scheme Procedure} $acos x +Return the arccosine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$atan") +@deffn {Scheme Procedure} $atan x +Return the arctangent of @var{x} in the range @minus{}@math{PI/2} to +@math{PI/2}. +@end deffn + +@deffn {Scheme Procedure} $atan2 x y +@deffnx {C Function} scm_sys_atan2 (x, y) +Return the arc tangent of the two arguments @var{x} and +@var{y}. This is similar to calculating the arc tangent of +@var{x} / @var{y}, except that the signs of both arguments +are used to determine the quadrant of the result. This +procedure does not accept complex arguments. +@end deffn + +@c begin (texi-doc-string "guile" "$exp") +@deffn {Scheme Procedure} $exp x +Return e to the power of @var{x}, where e is the base of natural +logarithms (2.71828@dots{}). +@end deffn + +@c begin (texi-doc-string "guile" "$log") +@deffn {Scheme Procedure} $log x +Return the natural logarithm of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$sinh") +@deffn {Scheme Procedure} $sinh x +Return the hyperbolic sine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$cosh") +@deffn {Scheme Procedure} $cosh x +Return the hyperbolic cosine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$tanh") +@deffn {Scheme Procedure} $tanh x +Return the hyperbolic tangent of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$asinh") +@deffn {Scheme Procedure} $asinh x +Return the hyperbolic arcsine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$acosh") +@deffn {Scheme Procedure} $acosh x +Return the hyperbolic arccosine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$atanh") +@deffn {Scheme Procedure} $atanh x +Return the hyperbolic arctangent of @var{x}. +@end deffn + +C functions for the above are provided by the standard mathematics +library. Naturally these expect and return @code{double} arguments +(@pxref{Mathematics,,, libc, GNU C Library Reference Manual}). + +@multitable {xx} {Scheme Procedure} {C Function} +@item @tab Scheme Procedure @tab C Function + +@item @tab @code{$abs} @tab @code{fabs} +@item @tab @code{$sqrt} @tab @code{sqrt} +@item @tab @code{$sin} @tab @code{sin} +@item @tab @code{$cos} @tab @code{cos} +@item @tab @code{$tan} @tab @code{tan} +@item @tab @code{$asin} @tab @code{asin} +@item @tab @code{$acos} @tab @code{acos} +@item @tab @code{$atan} @tab @code{atan} +@item @tab @code{$atan2} @tab @code{atan2} +@item @tab @code{$exp} @tab @code{exp} +@item @tab @code{$expt} @tab @code{pow} +@item @tab @code{$log} @tab @code{log} +@item @tab @code{$sinh} @tab @code{sinh} +@item @tab @code{$cosh} @tab @code{cosh} +@item @tab @code{$tanh} @tab @code{tanh} +@item @tab @code{$asinh} @tab @code{asinh} +@item @tab @code{$acosh} @tab @code{acosh} +@item @tab @code{$atanh} @tab @code{atanh} +@end multitable + +@code{asinh}, @code{acosh} and @code{atanh} are C99 standard but might +not be available on older systems. Guile provides the following +equivalents (on all systems). + +@deftypefn {C Function} double scm_asinh (double x) +@deftypefnx {C Function} double scm_acosh (double x) +@deftypefnx {C Function} double scm_atanh (double x) +Return the hyperbolic arcsine, arccosine or arctangent of @var{x} +respectively. +@end deftypefn + + +@node Bitwise Operations +@subsubsection Bitwise Operations + +For the following bitwise functions, negative numbers are treated as +infinite precision twos-complements. For instance @math{-6} is bits +@math{@dots{}111010}, with infinitely many ones on the left. It can +be seen that adding 6 (binary 110) to such a bit pattern gives all +zeros. + +@deffn {Scheme Procedure} logand n1 n2 @dots{} +@deffnx {C Function} scm_logand (n1, n2) +Return the bitwise @sc{and} of the integer arguments. + +@lisp +(logand) @result{} -1 +(logand 7) @result{} 7 +(logand #b111 #b011 #b001) @result{} 1 +@end lisp +@end deffn + +@deffn {Scheme Procedure} logior n1 n2 @dots{} +@deffnx {C Function} scm_logior (n1, n2) +Return the bitwise @sc{or} of the integer arguments. + +@lisp +(logior) @result{} 0 +(logior 7) @result{} 7 +(logior #b000 #b001 #b011) @result{} 3 +@end lisp +@end deffn + +@deffn {Scheme Procedure} logxor n1 n2 @dots{} +@deffnx {C Function} scm_loxor (n1, n2) +Return the bitwise @sc{xor} of the integer arguments. A bit is +set in the result if it is set in an odd number of arguments. + +@lisp +(logxor) @result{} 0 +(logxor 7) @result{} 7 +(logxor #b000 #b001 #b011) @result{} 2 +(logxor #b000 #b001 #b011 #b011) @result{} 1 +@end lisp +@end deffn + +@deffn {Scheme Procedure} lognot n +@deffnx {C Function} scm_lognot (n) +Return the integer which is the ones-complement of the integer +argument, ie.@: each 0 bit is changed to 1 and each 1 bit to 0. + +@lisp +(number->string (lognot #b10000000) 2) + @result{} "-10000001" +(number->string (lognot #b0) 2) + @result{} "-1" +@end lisp +@end deffn + +@deffn {Scheme Procedure} logtest j k +@deffnx {C Function} scm_logtest (j, k) +@lisp +(logtest j k) @equiv{} (not (zero? (logand j k))) + +(logtest #b0100 #b1011) @result{} #f +(logtest #b0100 #b0111) @result{} #t +@end lisp +@end deffn + +@deffn {Scheme Procedure} logbit? index j +@deffnx {C Function} scm_logbit_p (index, j) +@lisp +(logbit? index j) @equiv{} (logtest (integer-expt 2 index) j) + +(logbit? 0 #b1101) @result{} #t +(logbit? 1 #b1101) @result{} #f +(logbit? 2 #b1101) @result{} #t +(logbit? 3 #b1101) @result{} #t +(logbit? 4 #b1101) @result{} #f +@end lisp +@end deffn + +@deffn {Scheme Procedure} ash n cnt +@deffnx {C Function} scm_ash (n, cnt) +Return @var{n} shifted left by @var{cnt} bits, or shifted right if +@var{cnt} is negative. This is an ``arithmetic'' shift. + +This is effectively a multiplication by @m{2^{cnt}, 2^@var{cnt}}, and +when @var{cnt} is negative it's a division, rounded towards negative +infinity. (Note that this is not the same rounding as @code{quotient} +does.) + +With @var{n} viewed as an infinite precision twos complement, +@code{ash} means a left shift introducing zero bits, or a right shift +dropping bits. + +@lisp +(number->string (ash #b1 3) 2) @result{} "1000" +(number->string (ash #b1010 -1) 2) @result{} "101" + +;; -23 is bits ...11101001, -6 is bits ...111010 +(ash -23 -2) @result{} -6 +@end lisp +@end deffn + +@deffn {Scheme Procedure} logcount n +@deffnx {C Function} scm_logcount (n) +Return the number of bits in integer @var{n}. If integer is +positive, the 1-bits in its binary representation are counted. +If negative, the 0-bits in its two's-complement binary +representation are counted. If 0, 0 is returned. + +@lisp +(logcount #b10101010) + @result{} 4 +(logcount 0) + @result{} 0 +(logcount -2) + @result{} 1 +@end lisp +@end deffn + +@deffn {Scheme Procedure} integer-length n +@deffnx {C Function} scm_integer_length (n) +Return the number of bits necessary to represent @var{n}. + +For positive @var{n} this is how many bits to the most significant one +bit. For negative @var{n} it's how many bits to the most significant +zero bit in twos complement form. + +@lisp +(integer-length #b10101010) @result{} 8 +(integer-length #b1111) @result{} 4 +(integer-length 0) @result{} 0 +(integer-length -1) @result{} 0 +(integer-length -256) @result{} 8 +(integer-length -257) @result{} 9 +@end lisp +@end deffn + +@deffn {Scheme Procedure} integer-expt n k +@deffnx {C Function} scm_integer_expt (n, k) +Return @var{n} raised to the non-negative integer exponent +@var{k}. + +@lisp +(integer-expt 2 5) + @result{} 32 +(integer-expt -3 3) + @result{} -27 +@end lisp +@end deffn + +@deffn {Scheme Procedure} bit-extract n start end +@deffnx {C Function} scm_bit_extract (n, start, end) +Return the integer composed of the @var{start} (inclusive) +through @var{end} (exclusive) bits of @var{n}. The +@var{start}th bit becomes the 0-th bit in the result. + +@lisp +(number->string (bit-extract #b1101101010 0 4) 2) + @result{} "1010" +(number->string (bit-extract #b1101101010 4 9) 2) + @result{} "10110" +@end lisp +@end deffn + + +@node Random +@subsubsection Random Number Generation + +Pseudo-random numbers are generated from a random state object, which +can be created with @code{seed->random-state}. The @var{state} +parameter to the various functions below is optional, it defaults to +the state object in the @code{*random-state*} variable. + +@deffn {Scheme Procedure} copy-random-state [state] +@deffnx {C Function} scm_copy_random_state (state) +Return a copy of the random state @var{state}. +@end deffn + +@deffn {Scheme Procedure} random n [state] +@deffnx {C Function} scm_random (n, state) +Return a number in [0, @var{n}). + +Accepts a positive integer or real n and returns a +number of the same type between zero (inclusive) and +@var{n} (exclusive). The values returned have a uniform +distribution. +@end deffn + +@deffn {Scheme Procedure} random:exp [state] +@deffnx {C Function} scm_random_exp (state) +Return an inexact real in an exponential distribution with mean +1. For an exponential distribution with mean @var{u} use @code{(* +@var{u} (random:exp))}. +@end deffn + +@deffn {Scheme Procedure} random:hollow-sphere! vect [state] +@deffnx {C Function} scm_random_hollow_sphere_x (vect, state) +Fills @var{vect} with inexact real random numbers the sum of whose +squares is equal to 1.0. Thinking of @var{vect} as coordinates in +space of dimension @var{n} @math{=} @code{(vector-length @var{vect})}, +the coordinates are uniformly distributed over the surface of the unit +n-sphere. +@end deffn + +@deffn {Scheme Procedure} random:normal [state] +@deffnx {C Function} scm_random_normal (state) +Return an inexact real in a normal distribution. The distribution +used has mean 0 and standard deviation 1. For a normal distribution +with mean @var{m} and standard deviation @var{d} use @code{(+ @var{m} +(* @var{d} (random:normal)))}. +@end deffn + +@deffn {Scheme Procedure} random:normal-vector! vect [state] +@deffnx {C Function} scm_random_normal_vector_x (vect, state) +Fills @var{vect} with inexact real random numbers that are +independent and standard normally distributed +(i.e., with mean 0 and variance 1). +@end deffn + +@deffn {Scheme Procedure} random:solid-sphere! vect [state] +@deffnx {C Function} scm_random_solid_sphere_x (vect, state) +Fills @var{vect} with inexact real random numbers the sum of whose +squares is less than 1.0. Thinking of @var{vect} as coordinates in +space of dimension @var{n} @math{=} @code{(vector-length @var{vect})}, +the coordinates are uniformly distributed within the unit +@var{n}-sphere. The sum of the squares of the numbers is returned. +@c FIXME: What does this mean, particularly the n-sphere part? +@end deffn + +@deffn {Scheme Procedure} random:uniform [state] +@deffnx {C Function} scm_random_uniform (state) +Return a uniformly distributed inexact real random number in +[0,1). +@end deffn + +@deffn {Scheme Procedure} seed->random-state seed +@deffnx {C Function} scm_seed_to_random_state (seed) +Return a new random state using @var{seed}. +@end deffn + +@defvar *random-state* +The global random state used by the above functions when the +@var{state} parameter is not given. +@end defvar + + +@node Characters +@subsection Characters +@tpindex Characters + +@noindent +[@strong{FIXME}: how do you specify regular (non-control) characters?] + +Most of the ``control characters'' (those below codepoint 32) in the +@acronym{ASCII} character set, as well as the space, may be referred +to by name: for example, @code{#\tab}, @code{#\esc}, @code{#\stx}, and +so on. The following table describes the @acronym{ASCII} names for +each character. + +@multitable @columnfractions .25 .25 .25 .25 +@item 0 = @code{#\nul} + @tab 1 = @code{#\soh} + @tab 2 = @code{#\stx} + @tab 3 = @code{#\etx} +@item 4 = @code{#\eot} + @tab 5 = @code{#\enq} + @tab 6 = @code{#\ack} + @tab 7 = @code{#\bel} +@item 8 = @code{#\bs} + @tab 9 = @code{#\ht} + @tab 10 = @code{#\nl} + @tab 11 = @code{#\vt} +@item 12 = @code{#\np} + @tab 13 = @code{#\cr} + @tab 14 = @code{#\so} + @tab 15 = @code{#\si} +@item 16 = @code{#\dle} + @tab 17 = @code{#\dc1} + @tab 18 = @code{#\dc2} + @tab 19 = @code{#\dc3} +@item 20 = @code{#\dc4} + @tab 21 = @code{#\nak} + @tab 22 = @code{#\syn} + @tab 23 = @code{#\etb} +@item 24 = @code{#\can} + @tab 25 = @code{#\em} + @tab 26 = @code{#\sub} + @tab 27 = @code{#\esc} +@item 28 = @code{#\fs} + @tab 29 = @code{#\gs} + @tab 30 = @code{#\rs} + @tab 31 = @code{#\us} +@item 32 = @code{#\sp} +@end multitable + +The ``delete'' character (octal 177) may be referred to with the name +@code{#\del}. + +Several characters have more than one name: + +@multitable {@code{#\backspace}} {Original} +@item Alias @tab Original +@item @code{#\space} @tab @code{#\sp} +@item @code{#\newline} @tab @code{#\nl} +@item @code{#\tab} @tab @code{#\ht} +@item @code{#\backspace} @tab @code{#\bs} +@item @code{#\return} @tab @code{#\cr} +@item @code{#\page} @tab @code{#\np} +@item @code{#\null} @tab @code{#\nul} +@end multitable + +@rnindex char? +@deffn {Scheme Procedure} char? x +@deffnx {C Function} scm_char_p (x) +Return @code{#t} iff @var{x} is a character, else @code{#f}. +@end deffn + +@rnindex char=? +@deffn {Scheme Procedure} char=? x y +Return @code{#t} iff @var{x} is the same character as @var{y}, else @code{#f}. +@end deffn + +@rnindex char<? +@deffn {Scheme Procedure} char<? x y +Return @code{#t} iff @var{x} is less than @var{y} in the @acronym{ASCII} sequence, +else @code{#f}. +@end deffn + +@rnindex char<=? +@deffn {Scheme Procedure} char<=? x y +Return @code{#t} iff @var{x} is less than or equal to @var{y} in the +@acronym{ASCII} sequence, else @code{#f}. +@end deffn + +@rnindex char>? +@deffn {Scheme Procedure} char>? x y +Return @code{#t} iff @var{x} is greater than @var{y} in the @acronym{ASCII} +sequence, else @code{#f}. +@end deffn + +@rnindex char>=? +@deffn {Scheme Procedure} char>=? x y +Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the +@acronym{ASCII} sequence, else @code{#f}. +@end deffn + +@rnindex char-ci=? +@deffn {Scheme Procedure} char-ci=? x y +Return @code{#t} iff @var{x} is the same character as @var{y} ignoring +case, else @code{#f}. +@end deffn + +@rnindex char-ci<? +@deffn {Scheme Procedure} char-ci<? x y +Return @code{#t} iff @var{x} is less than @var{y} in the @acronym{ASCII} sequence +ignoring case, else @code{#f}. +@end deffn + +@rnindex char-ci<=? +@deffn {Scheme Procedure} char-ci<=? x y +Return @code{#t} iff @var{x} is less than or equal to @var{y} in the +@acronym{ASCII} sequence ignoring case, else @code{#f}. +@end deffn + +@rnindex char-ci>? +@deffn {Scheme Procedure} char-ci>? x y +Return @code{#t} iff @var{x} is greater than @var{y} in the @acronym{ASCII} +sequence ignoring case, else @code{#f}. +@end deffn + +@rnindex char-ci>=? +@deffn {Scheme Procedure} char-ci>=? x y +Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the +@acronym{ASCII} sequence ignoring case, else @code{#f}. +@end deffn + +@rnindex char-alphabetic? +@deffn {Scheme Procedure} char-alphabetic? chr +@deffnx {C Function} scm_char_alphabetic_p (chr) +Return @code{#t} iff @var{chr} is alphabetic, else @code{#f}. +Alphabetic means the same thing as the @code{isalpha} C library function. +@end deffn + +@rnindex char-numeric? +@deffn {Scheme Procedure} char-numeric? chr +@deffnx {C Function} scm_char_numeric_p (chr) +Return @code{#t} iff @var{chr} is numeric, else @code{#f}. +Numeric means the same thing as the @code{isdigit} C library function. +@end deffn + +@rnindex char-whitespace? +@deffn {Scheme Procedure} char-whitespace? chr +@deffnx {C Function} scm_char_whitespace_p (chr) +Return @code{#t} iff @var{chr} is whitespace, else @code{#f}. +Whitespace means the same thing as the @code{isspace} C library function. +@end deffn + +@rnindex char-upper-case? +@deffn {Scheme Procedure} char-upper-case? chr +@deffnx {C Function} scm_char_upper_case_p (chr) +Return @code{#t} iff @var{chr} is uppercase, else @code{#f}. +Uppercase means the same thing as the @code{isupper} C library function. +@end deffn + +@rnindex char-lower-case? +@deffn {Scheme Procedure} char-lower-case? chr +@deffnx {C Function} scm_char_lower_case_p (chr) +Return @code{#t} iff @var{chr} is lowercase, else @code{#f}. +Lowercase means the same thing as the @code{islower} C library function. +@end deffn + +@deffn {Scheme Procedure} char-is-both? chr +@deffnx {C Function} scm_char_is_both_p (chr) +Return @code{#t} iff @var{chr} is either uppercase or lowercase, else +@code{#f}. Uppercase and lowercase are as defined by the +@code{isupper} and @code{islower} C library functions. +@end deffn + +@rnindex char->integer +@deffn {Scheme Procedure} char->integer chr +@deffnx {C Function} scm_char_to_integer (chr) +Return the number corresponding to ordinal position of @var{chr} in the +@acronym{ASCII} sequence. +@end deffn + +@rnindex integer->char +@deffn {Scheme Procedure} integer->char n +@deffnx {C Function} scm_integer_to_char (n) +Return the character at position @var{n} in the @acronym{ASCII} sequence. +@end deffn + +@rnindex char-upcase +@deffn {Scheme Procedure} char-upcase chr +@deffnx {C Function} scm_char_upcase (chr) +Return the uppercase character version of @var{chr}. +@end deffn + +@rnindex char-downcase +@deffn {Scheme Procedure} char-downcase chr +@deffnx {C Function} scm_char_downcase (chr) +Return the lowercase character version of @var{chr}. +@end deffn + +@xref{Classification of Characters,,,libc,GNU C Library Reference +Manual}, for information about the @code{is*} Standard C functions +mentioned above. + + +@node Strings +@subsection Strings +@tpindex Strings + +Strings are fixed-length sequences of characters. They can be created +by calling constructor procedures, but they can also literally get +entered at the @acronym{REPL} or in Scheme source files. + +@c Guile provides a rich set of string processing procedures, because text +@c handling is very important when Guile is used as a scripting language. + +Strings always carry the information about how many characters they are +composed of with them, so there is no special end-of-string character, +like in C. That means that Scheme strings can contain any character, +even the @samp{NUL} character @samp{\0}. But note: Since most operating +system calls dealing with strings (such as for file operations) expect +strings to be zero-terminated, they might do unexpected things when +called with string containing unusual characters. + +@menu +* String Syntax:: Read syntax for strings. +* String Predicates:: Testing strings for certain properties. +* String Constructors:: Creating new string objects. +* List/String Conversion:: Converting from/to lists of characters. +* String Selection:: Select portions from strings. +* String Modification:: Modify parts or whole strings. +* String Comparison:: Lexicographic ordering predicates. +* String Searching:: Searching in strings. +* Alphabetic Case Mapping:: Convert the alphabetic case of strings. +* Appending Strings:: Appending strings to form a new string. +@end menu + +@node String Syntax +@subsubsection String Read Syntax + +@c In the following @code is used to get a good font in TeX etc, but +@c is omitted for Info format, so as not to risk any confusion over +@c whether surrounding ` ' quotes are part of the escape or are +@c special in a string (they're not). + +The read syntax for strings is an arbitrarily long sequence of +characters enclosed in double quotes (@nicode{"}). @footnote{Actually, +the current implementation restricts strings to a length of +@math{2^24}, or 16,777,216, characters. Sorry.} + +Backslash is an escape character and can be used to insert the +following special characters. @nicode{\"} and @nicode{\\} are R5RS +standard, the rest are Guile extensions, notice they follow C string +syntax. + +@table @asis +@item @nicode{\\} +Backslash character. + +@item @nicode{\"} +Double quote character (an unescaped @nicode{"} is otherwise the end +of the string). + +@item @nicode{\0} +NUL character (ASCII 0). + +@item @nicode{\a} +Bell character (ASCII 7). + +@item @nicode{\f} +Formfeed character (ASCII 12). + +@item @nicode{\n} +Newline character (ASCII 10). + +@item @nicode{\r} +Carriage return character (ASCII 13). + +@item @nicode{\t} +Tab character (ASCII 9). + +@item @nicode{\v} +Vertical tab character (ASCII 11). + +@item @nicode{\xHH} +Character code given by two hexadecimal digits. For example +@nicode{\x7f} for an ASCII DEL (127). +@end table + +@noindent +The following are examples of string literals: + +@lisp +"foo" +"bar plonk" +"Hello World" +"\"Hi\", he said." +@end lisp + + +@node String Predicates +@subsubsection String Predicates + +The following procedures can be used to check whether a given string +fulfills some specified property. + +@rnindex string? +@deffn {Scheme Procedure} string? obj +@deffnx {C Function} scm_string_p (obj) +Return @code{#t} if @var{obj} is a string, else @code{#f}. +@end deffn + +@deffn {Scheme Procedure} string-null? str +@deffnx {C Function} scm_string_null_p (str) +Return @code{#t} if @var{str}'s length is zero, and +@code{#f} otherwise. +@lisp +(string-null? "") @result{} #t +y @result{} "foo" +(string-null? y) @result{} #f +@end lisp +@end deffn + +@node String Constructors +@subsubsection String Constructors + +The string constructor procedures create new string objects, possibly +initializing them with some specified character data. + +@c FIXME::martin: list->string belongs into `List/String Conversion' + +@rnindex string +@rnindex list->string +@deffn {Scheme Procedure} string . chrs +@deffnx {Scheme Procedure} list->string chrs +@deffnx {C Function} scm_string (chrs) +Return a newly allocated string composed of the arguments, +@var{chrs}. +@end deffn + +@rnindex make-string +@deffn {Scheme Procedure} make-string k [chr] +@deffnx {C Function} scm_make_string (k, chr) +Return a newly allocated string of +length @var{k}. If @var{chr} is given, then all elements of +the string are initialized to @var{chr}, otherwise the contents +of the @var{string} are unspecified. +@end deffn + +@node List/String Conversion +@subsubsection List/String conversion + +When processing strings, it is often convenient to first convert them +into a list representation by using the procedure @code{string->list}, +work with the resulting list, and then convert it back into a string. +These procedures are useful for similar tasks. + +@rnindex string->list +@deffn {Scheme Procedure} string->list str +@deffnx {C Function} scm_string_to_list (str) +Return a newly allocated list of the characters that make up +the given string @var{str}. @code{string->list} and +@code{list->string} are inverses as far as @samp{equal?} is +concerned. +@end deffn + +@deffn {Scheme Procedure} string-split str chr +@deffnx {C Function} scm_string_split (str, chr) +Split the string @var{str} into the a list of the substrings delimited +by appearances of the character @var{chr}. Note that an empty substring +between separator characters will result in an empty string in the +result list. + +@lisp +(string-split "root:x:0:0:root:/root:/bin/bash" #\:) +@result{} +("root" "x" "0" "0" "root" "/root" "/bin/bash") + +(string-split "::" #\:) +@result{} +("" "" "") + +(string-split "" #\:) +@result{} +("") +@end lisp +@end deffn + + +@node String Selection +@subsubsection String Selection + +Portions of strings can be extracted by these procedures. +@code{string-ref} delivers individual characters whereas +@code{substring} can be used to extract substrings from longer strings. + +@rnindex string-length +@deffn {Scheme Procedure} string-length string +@deffnx {C Function} scm_string_length (string) +Return the number of characters in @var{string}. +@end deffn + +@rnindex string-ref +@deffn {Scheme Procedure} string-ref str k +@deffnx {C Function} scm_string_ref (str, k) +Return character @var{k} of @var{str} using zero-origin +indexing. @var{k} must be a valid index of @var{str}. +@end deffn + +@rnindex string-copy +@deffn {Scheme Procedure} string-copy str +@deffnx {C Function} scm_string_copy (str) +Return a newly allocated copy of the given @var{string}. +@end deffn + +@rnindex substring +@deffn {Scheme Procedure} substring str start [end] +@deffnx {C Function} scm_substring (str, start, end) +Return a newly allocated string formed from the characters +of @var{str} beginning with index @var{start} (inclusive) and +ending with index @var{end} (exclusive). +@var{str} must be a string, @var{start} and @var{end} must be +exact integers satisfying: + +0 <= @var{start} <= @var{end} <= @code{(string-length @var{str})}. +@end deffn + +@node String Modification +@subsubsection String Modification + +These procedures are for modifying strings in-place. This means that the +result of the operation is not a new string; instead, the original string's +memory representation is modified. + +@rnindex string-set! +@deffn {Scheme Procedure} string-set! str k chr +@deffnx {C Function} scm_string_set_x (str, k, chr) +Store @var{chr} in element @var{k} of @var{str} and return +an unspecified value. @var{k} must be a valid index of +@var{str}. +@end deffn + +@rnindex string-fill! +@deffn {Scheme Procedure} string-fill! str chr +@deffnx {C Function} scm_string_fill_x (str, chr) +Store @var{char} in every element of the given @var{string} and +return an unspecified value. +@end deffn + +@deffn {Scheme Procedure} substring-fill! str start end fill +@deffnx {C Function} scm_substring_fill_x (str, start, end, fill) +Change every character in @var{str} between @var{start} and +@var{end} to @var{fill}. + +@lisp +(define y "abcdefg") +(substring-fill! y 1 3 #\r) +y +@result{} "arrdefg" +@end lisp +@end deffn + +@deffn {Scheme Procedure} substring-move! str1 start1 end1 str2 start2 +@deffnx {C Function} scm_substring_move_x (str1, start1, end1, str2, start2) +Copy the substring of @var{str1} bounded by @var{start1} and @var{end1} +into @var{str2} beginning at position @var{start2}. +@var{str1} and @var{str2} can be the same string. +@end deffn + + +@node String Comparison +@subsubsection String Comparison + +The procedures in this section are similar to the character ordering +predicates (@pxref{Characters}), but are defined on character sequences. +They all return @code{#t} on success and @code{#f} on failure. The +predicates ending in @code{-ci} ignore the character case when comparing +strings. + + +@rnindex string=? +@deffn {Scheme Procedure} string=? s1 s2 +Lexicographic equality predicate; return @code{#t} if the two +strings are the same length and contain the same characters in +the same positions, otherwise return @code{#f}. + +The procedure @code{string-ci=?} treats upper and lower case +letters as though they were the same character, but +@code{string=?} treats upper and lower case as distinct +characters. +@end deffn + +@rnindex string<? +@deffn {Scheme Procedure} string<? s1 s2 +Lexicographic ordering predicate; return @code{#t} if @var{s1} +is lexicographically less than @var{s2}. +@end deffn + +@rnindex string<=? +@deffn {Scheme Procedure} string<=? s1 s2 +Lexicographic ordering predicate; return @code{#t} if @var{s1} +is lexicographically less than or equal to @var{s2}. +@end deffn + +@rnindex string>? +@deffn {Scheme Procedure} string>? s1 s2 +Lexicographic ordering predicate; return @code{#t} if @var{s1} +is lexicographically greater than @var{s2}. +@end deffn + +@rnindex string>=? +@deffn {Scheme Procedure} string>=? s1 s2 +Lexicographic ordering predicate; return @code{#t} if @var{s1} +is lexicographically greater than or equal to @var{s2}. +@end deffn + +@rnindex string-ci=? +@deffn {Scheme Procedure} string-ci=? s1 s2 +Case-insensitive string equality predicate; return @code{#t} if +the two strings are the same length and their component +characters match (ignoring case) at each position; otherwise +return @code{#f}. +@end deffn + +@rnindex string-ci< +@deffn {Scheme Procedure} string-ci<? s1 s2 +Case insensitive lexicographic ordering predicate; return +@code{#t} if @var{s1} is lexicographically less than @var{s2} +regardless of case. +@end deffn + +@rnindex string<=? +@deffn {Scheme Procedure} string-ci<=? s1 s2 +Case insensitive lexicographic ordering predicate; return +@code{#t} if @var{s1} is lexicographically less than or equal +to @var{s2} regardless of case. +@end deffn + +@rnindex string-ci>? +@deffn {Scheme Procedure} string-ci>? s1 s2 +Case insensitive lexicographic ordering predicate; return +@code{#t} if @var{s1} is lexicographically greater than +@var{s2} regardless of case. +@end deffn + +@rnindex string-ci>=? +@deffn {Scheme Procedure} string-ci>=? s1 s2 +Case insensitive lexicographic ordering predicate; return +@code{#t} if @var{s1} is lexicographically greater than or +equal to @var{s2} regardless of case. +@end deffn + + +@node String Searching +@subsubsection String Searching + +When searching for the index of a character in a string, these +procedures can be used. + +@deffn {Scheme Procedure} string-index str chr [frm [to]] +@deffnx {C Function} scm_string_index (str, chr, frm, to) +Return the index of the first occurrence of @var{chr} in +@var{str}. The optional integer arguments @var{frm} and +@var{to} limit the search to a portion of the string. This +procedure essentially implements the @code{index} or +@code{strchr} functions from the C library. + +@lisp +(string-index "weiner" #\e) +@result{} 1 + +(string-index "weiner" #\e 2) +@result{} 4 + +(string-index "weiner" #\e 2 4) +@result{} #f +@end lisp +@end deffn + +@deffn {Scheme Procedure} string-rindex str chr [frm [to]] +@deffnx {C Function} scm_string_rindex (str, chr, frm, to) +Like @code{string-index}, but search from the right of the +string rather than from the left. This procedure essentially +implements the @code{rindex} or @code{strrchr} functions from +the C library. + +@lisp +(string-rindex "weiner" #\e) +@result{} 4 + +(string-rindex "weiner" #\e 2 4) +@result{} #f + +(string-rindex "weiner" #\e 2 5) +@result{} 4 +@end lisp +@end deffn + +@node Alphabetic Case Mapping +@subsubsection Alphabetic Case Mapping + +These are procedures for mapping strings to their upper- or lower-case +equivalents, respectively, or for capitalizing strings. + +@deffn {Scheme Procedure} string-upcase str +@deffnx {C Function} scm_string_upcase (str) +Return a freshly allocated string containing the characters of +@var{str} in upper case. +@end deffn + +@deffn {Scheme Procedure} string-upcase! str +@deffnx {C Function} scm_string_upcase_x (str) +Destructively upcase every character in @var{str} and return +@var{str}. +@lisp +y @result{} "arrdefg" +(string-upcase! y) @result{} "ARRDEFG" +y @result{} "ARRDEFG" +@end lisp +@end deffn + +@deffn {Scheme Procedure} string-downcase str +@deffnx {C Function} scm_string_downcase (str) +Return a freshly allocation string containing the characters in +@var{str} in lower case. +@end deffn + +@deffn {Scheme Procedure} string-downcase! str +@deffnx {C Function} scm_string_downcase_x (str) +Destructively downcase every character in @var{str} and return +@var{str}. +@lisp +y @result{} "ARRDEFG" +(string-downcase! y) @result{} "arrdefg" +y @result{} "arrdefg" +@end lisp +@end deffn + +@deffn {Scheme Procedure} string-capitalize str +@deffnx {C Function} scm_string_capitalize (str) +Return a freshly allocated string with the characters in +@var{str}, where the first character of every word is +capitalized. +@end deffn + +@deffn {Scheme Procedure} string-capitalize! str +@deffnx {C Function} scm_string_capitalize_x (str) +Upcase the first character of every word in @var{str} +destructively and return @var{str}. + +@lisp +y @result{} "hello world" +(string-capitalize! y) @result{} "Hello World" +y @result{} "Hello World" +@end lisp +@end deffn + + +@node Appending Strings +@subsubsection Appending Strings + +The procedure @code{string-append} appends several strings together to +form a longer result string. + +@rnindex string-append +@deffn {Scheme Procedure} string-append . args +@deffnx {C Function} scm_string_append (args) +Return a newly allocated string whose characters form the +concatenation of the given strings, @var{args}. + +@example +(let ((h "hello ")) + (string-append h "world")) +@result{} "hello world" +@end example +@end deffn + + +@node Regular Expressions +@subsection Regular Expressions +@tpindex Regular expressions + +@cindex regular expressions +@cindex regex +@cindex emacs regexp + +A @dfn{regular expression} (or @dfn{regexp}) is a pattern that +describes a whole class of strings. A full description of regular +expressions and their syntax is beyond the scope of this manual; +an introduction can be found in the Emacs manual (@pxref{Regexps, +, Syntax of Regular Expressions, emacs, The GNU Emacs Manual}), or +in many general Unix reference books. + +If your system does not include a POSIX regular expression library, +and you have not linked Guile with a third-party regexp library such +as Rx, these functions will not be available. You can tell whether +your Guile installation includes regular expression support by +checking whether @code{(provided? 'regex)} returns true. + +The following regexp and string matching features are provided by the +@code{(ice-9 regex)} module. Before using the described functions, +you should load this module by executing @code{(use-modules (ice-9 +regex))}. + +@menu +* Regexp Functions:: Functions that create and match regexps. +* Match Structures:: Finding what was matched by a regexp. +* Backslash Escapes:: Removing the special meaning of regexp + meta-characters. +@end menu + + +@node Regexp Functions +@subsubsection Regexp Functions + +By default, Guile supports POSIX extended regular expressions. +That means that the characters @samp{(}, @samp{)}, @samp{+} and +@samp{?} are special, and must be escaped if you wish to match the +literal characters. + +This regular expression interface was modeled after that +implemented by SCSH, the Scheme Shell. It is intended to be +upwardly compatible with SCSH regular expressions. + +@deffn {Scheme Procedure} string-match pattern str [start] +Compile the string @var{pattern} into a regular expression and compare +it with @var{str}. The optional numeric argument @var{start} specifies +the position of @var{str} at which to begin matching. + +@code{string-match} returns a @dfn{match structure} which +describes what, if anything, was matched by the regular +expression. @xref{Match Structures}. If @var{str} does not match +@var{pattern} at all, @code{string-match} returns @code{#f}. +@end deffn + +Two examples of a match follow. In the first example, the pattern +matches the four digits in the match string. In the second, the pattern +matches nothing. + +@example +(string-match "[0-9][0-9][0-9][0-9]" "blah2002") +@result{} #("blah2002" (4 . 8)) + +(string-match "[A-Za-z]" "123456") +@result{} #f +@end example + +Each time @code{string-match} is called, it must compile its +@var{pattern} argument into a regular expression structure. This +operation is expensive, which makes @code{string-match} inefficient if +the same regular expression is used several times (for example, in a +loop). For better performance, you can compile a regular expression in +advance and then match strings against the compiled regexp. + +@deffn {Scheme Procedure} make-regexp pat flag@dots{} +@deffnx {C Function} scm_make_regexp (pat, flaglst) +Compile the regular expression described by @var{pat}, and +return the compiled regexp structure. If @var{pat} does not +describe a legal regular expression, @code{make-regexp} throws +a @code{regular-expression-syntax} error. + +The @var{flag} arguments change the behavior of the compiled +regular expression. The following values may be supplied: + +@defvar regexp/icase +Consider uppercase and lowercase letters to be the same when +matching. +@end defvar + +@defvar regexp/newline +If a newline appears in the target string, then permit the +@samp{^} and @samp{$} operators to match immediately after or +immediately before the newline, respectively. Also, the +@samp{.} and @samp{[^...]} operators will never match a newline +character. The intent of this flag is to treat the target +string as a buffer containing many lines of text, and the +regular expression as a pattern that may match a single one of +those lines. +@end defvar + +@defvar regexp/basic +Compile a basic (``obsolete'') regexp instead of the extended +(``modern'') regexps that are the default. Basic regexps do +not consider @samp{|}, @samp{+} or @samp{?} to be special +characters, and require the @samp{@{...@}} and @samp{(...)} +metacharacters to be backslash-escaped (@pxref{Backslash +Escapes}). There are several other differences between basic +and extended regular expressions, but these are the most +significant. +@end defvar + +@defvar regexp/extended +Compile an extended regular expression rather than a basic +regexp. This is the default behavior; this flag will not +usually be needed. If a call to @code{make-regexp} includes +both @code{regexp/basic} and @code{regexp/extended} flags, the +one which comes last will override the earlier one. +@end defvar +@end deffn + +@deffn {Scheme Procedure} regexp-exec rx str [start [flags]] +@deffnx {C Function} scm_regexp_exec (rx, str, start, flags) +Match the compiled regular expression @var{rx} against +@code{str}. If the optional integer @var{start} argument is +provided, begin matching from that position in the string. +Return a match structure describing the results of the match, +or @code{#f} if no match could be found. + +The @var{flags} arguments change the matching behavior. +The following flags may be supplied: + +@defvar regexp/notbol +Operator @samp{^} always fails (unless @code{regexp/newline} +is used). Use this when the beginning of the string should +not be considered the beginning of a line. +@end defvar + +@defvar regexp/noteol +Operator @samp{$} always fails (unless @code{regexp/newline} +is used). Use this when the end of the string should not be +considered the end of a line. +@end defvar +@end deffn + +@lisp +;; Regexp to match uppercase letters +(define r (make-regexp "[A-Z]*")) + +;; Regexp to match letters, ignoring case +(define ri (make-regexp "[A-Z]*" regexp/icase)) + +;; Search for bob using regexp r +(match:substring (regexp-exec r "bob")) +@result{} "" ; no match + +;; Search for bob using regexp ri +(match:substring (regexp-exec ri "Bob")) +@result{} "Bob" ; matched case insensitive +@end lisp + +@deffn {Scheme Procedure} regexp? obj +@deffnx {C Function} scm_regexp_p (obj) +Return @code{#t} if @var{obj} is a compiled regular expression, +or @code{#f} otherwise. +@end deffn + +Regular expressions are commonly used to find patterns in one string and +replace them with the contents of another string. + +@c begin (scm-doc-string "regex.scm" "regexp-substitute") +@deffn {Scheme Procedure} regexp-substitute port match [item@dots{}] +Write to the output port @var{port} selected contents of the match +structure @var{match}. Each @var{item} specifies what should be +written, and may be one of the following arguments: + +@itemize @bullet +@item +A string. String arguments are written out verbatim. + +@item +An integer. The submatch with that number is written. + +@item +The symbol @samp{pre}. The portion of the matched string preceding +the regexp match is written. + +@item +The symbol @samp{post}. The portion of the matched string following +the regexp match is written. +@end itemize + +The @var{port} argument may be @code{#f}, in which case nothing is +written; instead, @code{regexp-substitute} constructs a string from the +specified @var{item}s and returns that. +@end deffn + +The following example takes a regular expression that matches a standard +@sc{yyyymmdd}-format date such as @code{"20020828"}. The +@code{regexp-substitute} call returns a string computed from the +information in the match structure, consisting of the fields and text +from the original string reordered and reformatted. + +@lisp +(define date-regex "([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])") +(define s "Date 20020429 12am.") +(define sm (string-match date-regex s)) +(regexp-substitute #f sm 'pre 2 "-" 3 "-" 1 'post " (" 0 ")") +@result{} "Date 04-29-2002 12am. (20020429)" +@end lisp + +@c begin (scm-doc-string "regex.scm" "regexp-substitute") +@deffn {Scheme Procedure} regexp-substitute/global port regexp target [item@dots{}] +Similar to @code{regexp-substitute}, but can be used to perform global +substitutions on @var{str}. Instead of taking a match structure as an +argument, @code{regexp-substitute/global} takes two string arguments: a +@var{regexp} string describing a regular expression, and a @var{target} +string which should be matched against this regular expression. + +Each @var{item} behaves as in @code{regexp-substitute}, with the +following exceptions: + +@itemize @bullet +@item +A function may be supplied. When this function is called, it will be +passed one argument: a match structure for a given regular expression +match. It should return a string to be written out to @var{port}. + +@item +The @samp{post} symbol causes @code{regexp-substitute/global} to recurse +on the unmatched portion of @var{str}. This @emph{must} be supplied in +order to perform global search-and-replace on @var{str}; if it is not +present among the @var{item}s, then @code{regexp-substitute/global} will +return after processing a single match. +@end itemize +@end deffn + +The example above for @code{regexp-substitute} could be rewritten as +follows to remove the @code{string-match} stage: + +@lisp +(define date-regex "([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])") +(define s "Date 20020429 12am.") +(regexp-substitute/global #f date-regex s + 'pre 2 "-" 3 "-" 1 'post " (" 0 ")") +@result{} "Date 04-29-2002 12am. (20020429)" +@end lisp + + +@node Match Structures +@subsubsection Match Structures + +@cindex match structures + +A @dfn{match structure} is the object returned by @code{string-match} and +@code{regexp-exec}. It describes which portion of a string, if any, +matched the given regular expression. Match structures include: a +reference to the string that was checked for matches; the starting and +ending positions of the regexp match; and, if the regexp included any +parenthesized subexpressions, the starting and ending positions of each +submatch. + +In each of the regexp match functions described below, the @code{match} +argument must be a match structure returned by a previous call to +@code{string-match} or @code{regexp-exec}. Most of these functions +return some information about the original target string that was +matched against a regular expression; we will call that string +@var{target} for easy reference. + +@c begin (scm-doc-string "regex.scm" "regexp-match?") +@deffn {Scheme Procedure} regexp-match? obj +Return @code{#t} if @var{obj} is a match structure returned by a +previous call to @code{regexp-exec}, or @code{#f} otherwise. +@end deffn + +@c begin (scm-doc-string "regex.scm" "match:substring") +@deffn {Scheme Procedure} match:substring match [n] +Return the portion of @var{target} matched by subexpression number +@var{n}. Submatch 0 (the default) represents the entire regexp match. +If the regular expression as a whole matched, but the subexpression +number @var{n} did not match, return @code{#f}. +@end deffn + +@lisp +(define s (string-match "[0-9][0-9][0-9][0-9]" "blah2002foo")) +(match:substring s) +@result{} "2002" + +;; match starting at offset 6 in the string +(match:substring + (string-match "[0-9][0-9][0-9][0-9]" "blah987654" 6)) +@result{} "7654" +@end lisp + +@c begin (scm-doc-string "regex.scm" "match:start") +@deffn {Scheme Procedure} match:start match [n] +Return the starting position of submatch number @var{n}. +@end deffn + +In the following example, the result is 4, since the match starts at +character index 4: + +@lisp +(define s (string-match "[0-9][0-9][0-9][0-9]" "blah2002foo")) +(match:start s) +@result{} 4 +@end lisp + +@c begin (scm-doc-string "regex.scm" "match:end") +@deffn {Scheme Procedure} match:end match [n] +Return the ending position of submatch number @var{n}. +@end deffn + +In the following example, the result is 8, since the match runs between +characters 4 and 8 (i.e. the ``2002''). + +@lisp +(define s (string-match "[0-9][0-9][0-9][0-9]" "blah2002foo")) +(match:end s) +@result{} 8 +@end lisp + +@c begin (scm-doc-string "regex.scm" "match:prefix") +@deffn {Scheme Procedure} match:prefix match +Return the unmatched portion of @var{target} preceding the regexp match. + +@lisp +(define s (string-match "[0-9][0-9][0-9][0-9]" "blah2002foo")) +(match:prefix s) +@result{} "blah" +@end lisp +@end deffn + +@c begin (scm-doc-string "regex.scm" "match:suffix") +@deffn {Scheme Procedure} match:suffix match +Return the unmatched portion of @var{target} following the regexp match. +@end deffn + +@lisp +(define s (string-match "[0-9][0-9][0-9][0-9]" "blah2002foo")) +(match:suffix s) +@result{} "foo" +@end lisp + +@c begin (scm-doc-string "regex.scm" "match:count") +@deffn {Scheme Procedure} match:count match +Return the number of parenthesized subexpressions from @var{match}. +Note that the entire regular expression match itself counts as a +subexpression, and failed submatches are included in the count. +@end deffn + +@c begin (scm-doc-string "regex.scm" "match:string") +@deffn {Scheme Procedure} match:string match +Return the original @var{target} string. +@end deffn + +@lisp +(define s (string-match "[0-9][0-9][0-9][0-9]" "blah2002foo")) +(match:string s) +@result{} "blah2002foo" +@end lisp + + +@node Backslash Escapes +@subsubsection Backslash Escapes + +Sometimes you will want a regexp to match characters like @samp{*} or +@samp{$} exactly. For example, to check whether a particular string +represents a menu entry from an Info node, it would be useful to match +it against a regexp like @samp{^* [^:]*::}. However, this won't work; +because the asterisk is a metacharacter, it won't match the @samp{*} at +the beginning of the string. In this case, we want to make the first +asterisk un-magic. + +You can do this by preceding the metacharacter with a backslash +character @samp{\}. (This is also called @dfn{quoting} the +metacharacter, and is known as a @dfn{backslash escape}.) When Guile +sees a backslash in a regular expression, it considers the following +glyph to be an ordinary character, no matter what special meaning it +would ordinarily have. Therefore, we can make the above example work by +changing the regexp to @samp{^\* [^:]*::}. The @samp{\*} sequence tells +the regular expression engine to match only a single asterisk in the +target string. + +Since the backslash is itself a metacharacter, you may force a regexp to +match a backslash in the target string by preceding the backslash with +itself. For example, to find variable references in a @TeX{} program, +you might want to find occurrences of the string @samp{\let\} followed +by any number of alphabetic characters. The regular expression +@samp{\\let\\[A-Za-z]*} would do this: the double backslashes in the +regexp each match a single backslash in the target string. + +@c begin (scm-doc-string "regex.scm" "regexp-quote") +@deffn {Scheme Procedure} regexp-quote str +Quote each special character found in @var{str} with a backslash, and +return the resulting string. +@end deffn + +@strong{Very important:} Using backslash escapes in Guile source code +(as in Emacs Lisp or C) can be tricky, because the backslash character +has special meaning for the Guile reader. For example, if Guile +encounters the character sequence @samp{\n} in the middle of a string +while processing Scheme code, it replaces those characters with a +newline character. Similarly, the character sequence @samp{\t} is +replaced by a horizontal tab. Several of these @dfn{escape sequences} +are processed by the Guile reader before your code is executed. +Unrecognized escape sequences are ignored: if the characters @samp{\*} +appear in a string, they will be translated to the single character +@samp{*}. + +This translation is obviously undesirable for regular expressions, since +we want to be able to include backslashes in a string in order to +escape regexp metacharacters. Therefore, to make sure that a backslash +is preserved in a string in your Guile program, you must use @emph{two} +consecutive backslashes: + +@lisp +(define Info-menu-entry-pattern (make-regexp "^\\* [^:]*")) +@end lisp + +The string in this example is preprocessed by the Guile reader before +any code is executed. The resulting argument to @code{make-regexp} is +the string @samp{^\* [^:]*}, which is what we really want. + +This also means that in order to write a regular expression that matches +a single backslash character, the regular expression string in the +source code must include @emph{four} backslashes. Each consecutive pair +of backslashes gets translated by the Guile reader to a single +backslash, and the resulting double-backslash is interpreted by the +regexp engine as matching a single backslash character. Hence: + +@lisp +(define tex-variable-pattern (make-regexp "\\\\let\\\\=[A-Za-z]*")) +@end lisp + +The reason for the unwieldiness of this syntax is historical. Both +regular expression pattern matchers and Unix string processing systems +have traditionally used backslashes with the special meanings +described above. The POSIX regular expression specification and ANSI C +standard both require these semantics. Attempting to abandon either +convention would cause other kinds of compatibility problems, possibly +more severe ones. Therefore, without extending the Scheme reader to +support strings with different quoting conventions (an ungainly and +confusing extension when implemented in other languages), we must adhere +to this cumbersome escape syntax. + + +@node Symbols +@subsection Symbols +@tpindex Symbols + +Symbols in Scheme are widely used in three ways: as items of discrete +data, as lookup keys for alists and hash tables, and to denote variable +references. + +A @dfn{symbol} is similar to a string in that it is defined by a +sequence of characters. The sequence of characters is known as the +symbol's @dfn{name}. In the usual case --- that is, where the symbol's +name doesn't include any characters that could be confused with other +elements of Scheme syntax --- a symbol is written in a Scheme program by +writing the sequence of characters that make up the name, @emph{without} +any quotation marks or other special syntax. For example, the symbol +whose name is ``multiply-by-2'' is written, simply: + +@lisp +multiply-by-2 +@end lisp + +Notice how this differs from a @emph{string} with contents +``multiply-by-2'', which is written with double quotation marks, like +this: + +@lisp +"multiply-by-2" +@end lisp + +Looking beyond how they are written, symbols are different from strings +in two important respects. + +The first important difference is uniqueness. If the same-looking +string is read twice from two different places in a program, the result +is two @emph{different} string objects whose contents just happen to be +the same. If, on the other hand, the same-looking symbol is read twice +from two different places in a program, the result is the @emph{same} +symbol object both times. + +Given two read symbols, you can use @code{eq?} to test whether they are +the same (that is, have the same name). @code{eq?} is the most +efficient comparison operator in Scheme, and comparing two symbols like +this is as fast as comparing, for example, two numbers. Given two +strings, on the other hand, you must use @code{equal?} or +@code{string=?}, which are much slower comparison operators, to +determine whether the strings have the same contents. + +@lisp +(define sym1 (quote hello)) +(define sym2 (quote hello)) +(eq? sym1 sym2) @result{} #t + +(define str1 "hello") +(define str2 "hello") +(eq? str1 str2) @result{} #f +(equal? str1 str2) @result{} #t +@end lisp + +The second important difference is that symbols, unlike strings, are not +self-evaluating. This is why we need the @code{(quote @dots{})}s in the +example above: @code{(quote hello)} evaluates to the symbol named +"hello" itself, whereas an unquoted @code{hello} is @emph{read} as the +symbol named "hello" and evaluated as a variable reference @dots{} about +which more below (@pxref{Symbol Variables}). + +@menu +* Symbol Data:: Symbols as discrete data. +* Symbol Keys:: Symbols as lookup keys. +* Symbol Variables:: Symbols as denoting variables. +* Symbol Primitives:: Operations related to symbols. +* Symbol Props:: Function slots and property lists. +* Symbol Read Syntax:: Extended read syntax for symbols. +* Symbol Uninterned:: Uninterned symbols. +@end menu + + +@node Symbol Data +@subsubsection Symbols as Discrete Data + +Numbers and symbols are similar to the extent that they both lend +themselves to @code{eq?} comparison. But symbols are more descriptive +than numbers, because a symbol's name can be used directly to describe +the concept for which that symbol stands. + +For example, imagine that you need to represent some colours in a +computer program. Using numbers, you would have to choose arbitrarily +some mapping between numbers and colours, and then take care to use that +mapping consistently: + +@lisp +;; 1=red, 2=green, 3=purple + +(if (eq? (colour-of car) 1) + ...) +@end lisp + +@noindent +You can make the mapping more explicit and the code more readable by +defining constants: + +@lisp +(define red 1) +(define green 2) +(define purple 3) + +(if (eq? (colour-of car) red) + ...) +@end lisp + +@noindent +But the simplest and clearest approach is not to use numbers at all, but +symbols whose names specify the colours that they refer to: + +@lisp +(if (eq? (colour-of car) 'red) + ...) +@end lisp + +The descriptive advantages of symbols over numbers increase as the set +of concepts that you want to describe grows. Suppose that a car object +can have other properties as well, such as whether it has or uses: + +@itemize @bullet +@item +automatic or manual transmission +@item +leaded or unleaded fuel +@item +power steering (or not). +@end itemize + +@noindent +Then a car's combined property set could be naturally represented and +manipulated as a list of symbols: + +@lisp +(properties-of car1) +@result{} +(red manual unleaded power-steering) + +(if (memq 'power-steering (properties-of car1)) + (display "Unfit people can drive this car.\n") + (display "You'll need strong arms to drive this car!\n")) +@print{} +Unfit people can drive this car. +@end lisp + +Remember, the fundamental property of symbols that we are relying on +here is that an occurrence of @code{'red} in one part of a program is an +@emph{indistinguishable} symbol from an occurrence of @code{'red} in +another part of a program; this means that symbols can usefully be +compared using @code{eq?}. At the same time, symbols have naturally +descriptive names. This combination of efficiency and descriptive power +makes them ideal for use as discrete data. + + +@node Symbol Keys +@subsubsection Symbols as Lookup Keys + +Given their efficiency and descriptive power, it is natural to use +symbols as the keys in an association list or hash table. + +To illustrate this, consider a more structured representation of the car +properties example from the preceding subsection. Rather than +mixing all the properties up together in a flat list, we could use an +association list like this: + +@lisp +(define car1-properties '((colour . red) + (transmission . manual) + (fuel . unleaded) + (steering . power-assisted))) +@end lisp + +Notice how this structure is more explicit and extensible than the flat +list. For example it makes clear that @code{manual} refers to the +transmission rather than, say, the windows or the locking of the car. +It also allows further properties to use the same symbols among their +possible values without becoming ambiguous: + +@lisp +(define car1-properties '((colour . red) + (transmission . manual) + (fuel . unleaded) + (steering . power-assisted) + (seat-colour . red) + (locking . manual))) +@end lisp + +With a representation like this, it is easy to use the efficient +@code{assq-XXX} family of procedures (@pxref{Association Lists}) to +extract or change individual pieces of information: + +@lisp +(assq-ref car1-properties 'fuel) @result{} unleaded +(assq-ref car1-properties 'transmission) @result{} manual + +(assq-set! car1-properties 'seat-colour 'black) +@result{} +((colour . red) + (transmission . manual) + (fuel . unleaded) + (steering . power-assisted) + (seat-colour . black) + (locking . manual))) +@end lisp + +Hash tables also have keys, and exactly the same arguments apply to the +use of symbols in hash tables as in association lists. The hash value +that Guile uses to decide where to add a symbol-keyed entry to a hash +table can be obtained by calling the @code{symbol-hash} procedure: + +@deffn {Scheme Procedure} symbol-hash symbol +@deffnx {C Function} scm_symbol_hash (symbol) +Return a hash value for @var{symbol}. +@end deffn + +See @ref{Hash Tables} for information about hash tables in general, and +for why you might choose to use a hash table rather than an association +list. + + +@node Symbol Variables +@subsubsection Symbols as Denoting Variables + +When an unquoted symbol in a Scheme program is evaluated, it is +interpreted as a variable reference, and the result of the evaluation is +the appropriate variable's value. + +For example, when the expression @code{(string-length "abcd")} is read +and evaluated, the sequence of characters @code{string-length} is read +as the symbol whose name is "string-length". This symbol is associated +with a variable whose value is the procedure that implements string +length calculation. Therefore evaluation of the @code{string-length} +symbol results in that procedure. + +The details of the connection between an unquoted symbol and the +variable to which it refers are explained elsewhere. See @ref{Binding +Constructs}, for how associations between symbols and variables are +created, and @ref{Modules}, for how those associations are affected by +Guile's module system. + + +@node Symbol Primitives +@subsubsection Operations Related to Symbols + +Given any Scheme value, you can determine whether it is a symbol using +the @code{symbol?} primitive: + +@rnindex symbol? +@deffn {Scheme Procedure} symbol? obj +@deffnx {C Function} scm_symbol_p (obj) +Return @code{#t} if @var{obj} is a symbol, otherwise return +@code{#f}. +@end deffn + +Once you know that you have a symbol, you can obtain its name as a +string by calling @code{symbol->string}. Note that Guile differs by +default from R5RS on the details of @code{symbol->string} as regards +case-sensitivity: + +@rnindex symbol->string +@deffn {Scheme Procedure} symbol->string s +@deffnx {C Function} scm_symbol_to_string (s) +Return the name of symbol @var{s} as a string. By default, Guile reads +symbols case-sensitively, so the string returned will have the same case +variation as the sequence of characters that caused @var{s} to be +created. + +If Guile is set to read symbols case-insensitively (as specified by +R5RS), and @var{s} comes into being as part of a literal expression +(@pxref{Literal expressions,,,r5rs, The Revised^5 Report on Scheme}) or +by a call to the @code{read} or @code{string-ci->symbol} procedures, +Guile converts any alphabetic characters in the symbol's name to +lower case before creating the symbol object, so the string returned +here will be in lower case. + +If @var{s} was created by @code{string->symbol}, the case of characters +in the string returned will be the same as that in the string that was +passed to @code{string->symbol}, regardless of Guile's case-sensitivity +setting at the time @var{s} was created. + +It is an error to apply mutation procedures like @code{string-set!} to +strings returned by this procedure. +@end deffn + +Most symbols are created by writing them literally in code. However it +is also possible to create symbols programmatically using the following +@code{string->symbol} and @code{string-ci->symbol} procedures: + +@rnindex string->symbol +@deffn {Scheme Procedure} string->symbol string +@deffnx {C Function} scm_string_to_symbol (string) +Return the symbol whose name is @var{string}. This procedure can create +symbols with names containing special characters or letters in the +non-standard case, but it is usually a bad idea to create such symbols +because in some implementations of Scheme they cannot be read as +themselves. +@end deffn + +@deffn {Scheme Procedure} string-ci->symbol str +@deffnx {C Function} scm_string_ci_to_symbol (str) +Return the symbol whose name is @var{str}. If Guile is currently +reading symbols case-insensitively, @var{str} is converted to lowercase +before the returned symbol is looked up or created. +@end deffn + +The following examples illustrate Guile's detailed behaviour as regards +the case-sensitivity of symbols: + +@lisp +(read-enable 'case-insensitive) ; R5RS compliant behaviour + +(symbol->string 'flying-fish) @result{} "flying-fish" +(symbol->string 'Martin) @result{} "martin" +(symbol->string + (string->symbol "Malvina")) @result{} "Malvina" + +(eq? 'mISSISSIppi 'mississippi) @result{} #t +(string->symbol "mISSISSIppi") @result{} mISSISSIppi +(eq? 'bitBlt (string->symbol "bitBlt")) @result{} #f +(eq? 'LolliPop + (string->symbol (symbol->string 'LolliPop))) @result{} #t +(string=? "K. Harper, M.D." + (symbol->string + (string->symbol "K. Harper, M.D."))) @result{} #t + +(read-disable 'case-insensitive) ; Guile default behaviour + +(symbol->string 'flying-fish) @result{} "flying-fish" +(symbol->string 'Martin) @result{} "Martin" +(symbol->string + (string->symbol "Malvina")) @result{} "Malvina" + +(eq? 'mISSISSIppi 'mississippi) @result{} #f +(string->symbol "mISSISSIppi") @result{} mISSISSIppi +(eq? 'bitBlt (string->symbol "bitBlt")) @result{} #t +(eq? 'LolliPop + (string->symbol (symbol->string 'LolliPop))) @result{} #t +(string=? "K. Harper, M.D." + (symbol->string + (string->symbol "K. Harper, M.D."))) @result{} #t +@end lisp + +From C, there are lower level functions that construct a Scheme symbol +from a null terminated C string or from a sequence of bytes whose length +is specified explicitly. + +@deffn {C Function} scm_str2symbol (const char * name) +@deffnx {C Function} scm_mem2symbol (const char * name, size_t len) +Construct and return a Scheme symbol whose name is specified by +@var{name}. For @code{scm_str2symbol} @var{name} must be null +terminated; For @code{scm_mem2symbol} the length of @var{name} is +specified explicitly by @var{len}. +@end deffn + +Finally, some applications, especially those that generate new Scheme +code dynamically, need to generate symbols for use in the generated +code. The @code{gensym} primitive meets this need: + +@deffn {Scheme Procedure} gensym [prefix] +@deffnx {C Function} scm_gensym (prefix) +Create a new symbol with a name constructed from a prefix and a counter +value. The string @var{prefix} can be specified as an optional +argument. Default prefix is @samp{@w{ g}}. The counter is increased by 1 +at each call. There is no provision for resetting the counter. +@end deffn + +The symbols generated by @code{gensym} are @emph{likely} to be unique, +since their names begin with a space and it is only otherwise possible +to generate such symbols if a programmer goes out of their way to do +so. Uniqueness can be guaranteed by instead using uninterned symbols +(@pxref{Symbol Uninterned}), though they can't be usefully written out +and read back in. + + +@node Symbol Props +@subsubsection Function Slots and Property Lists + +In traditional Lisp dialects, symbols are often understood as having +three kinds of value at once: + +@itemize @bullet +@item +a @dfn{variable} value, which is used when the symbol appears in +code in a variable reference context + +@item +a @dfn{function} value, which is used when the symbol appears in +code in a function name position (i.e. as the first element in an +unquoted list) + +@item +a @dfn{property list} value, which is used when the symbol is given as +the first argument to Lisp's @code{put} or @code{get} functions. +@end itemize + +Although Scheme (as one of its simplifications with respect to Lisp) +does away with the distinction between variable and function namespaces, +Guile currently retains some elements of the traditional structure in +case they turn out to be useful when implementing translators for other +languages, in particular Emacs Lisp. + +Specifically, Guile symbols have two extra slots. for a symbol's +property list, and for its ``function value.'' The following procedures +are provided to access these slots. + +@deffn {Scheme Procedure} symbol-fref symbol +@deffnx {C Function} scm_symbol_fref (symbol) +Return the contents of @var{symbol}'s @dfn{function slot}. +@end deffn + +@deffn {Scheme Procedure} symbol-fset! symbol value +@deffnx {C Function} scm_symbol_fset_x (symbol, value) +Set the contents of @var{symbol}'s function slot to @var{value}. +@end deffn + +@deffn {Scheme Procedure} symbol-pref symbol +@deffnx {C Function} scm_symbol_pref (symbol) +Return the @dfn{property list} currently associated with @var{symbol}. +@end deffn + +@deffn {Scheme Procedure} symbol-pset! symbol value +@deffnx {C Function} scm_symbol_pset_x (symbol, value) +Set @var{symbol}'s property list to @var{value}. +@end deffn + +@deffn {Scheme Procedure} symbol-property sym prop +From @var{sym}'s property list, return the value for property +@var{prop}. The assumption is that @var{sym}'s property list is an +association list whose keys are distinguished from each other using +@code{equal?}; @var{prop} should be one of the keys in that list. If +the property list has no entry for @var{prop}, @code{symbol-property} +returns @code{#f}. +@end deffn + +@deffn {Scheme Procedure} set-symbol-property! sym prop val +In @var{sym}'s property list, set the value for property @var{prop} to +@var{val}, or add a new entry for @var{prop}, with value @var{val}, if +none already exists. For the structure of the property list, see +@code{symbol-property}. +@end deffn + +@deffn {Scheme Procedure} symbol-property-remove! sym prop +From @var{sym}'s property list, remove the entry for property +@var{prop}, if there is one. For the structure of the property list, +see @code{symbol-property}. +@end deffn + +Support for these extra slots may be removed in a future release, and it +is probably better to avoid using them. (In release 1.6, Guile itself +uses the property list slot sparingly, and the function slot not at +all.) For a more modern and Schemely approach to properties, see +@ref{Object Properties}. + + +@node Symbol Read Syntax +@subsubsection Extended Read Syntax for Symbols + +The read syntax for a symbol is a sequence of letters, digits, and +@dfn{extended alphabetic characters}, beginning with a character that +cannot begin a number. In addition, the special cases of @code{+}, +@code{-}, and @code{...} are read as symbols even though numbers can +begin with @code{+}, @code{-} or @code{.}. + +Extended alphabetic characters may be used within identifiers as if +they were letters. The set of extended alphabetic characters is: + +@example +! $ % & * + - . / : < = > ? @@ ^ _ ~ +@end example + +In addition to the standard read syntax defined above (which is taken +from R5RS (@pxref{Formal syntax,,,r5rs,The Revised^5 Report on +Scheme})), Guile provides an extended symbol read syntax that allows the +inclusion of unusual characters such as space characters, newlines and +parentheses. If (for whatever reason) you need to write a symbol +containing characters not mentioned above, you can do so as follows. + +@itemize @bullet +@item +Begin the symbol with the characters @code{#@{}, + +@item +write the characters of the symbol and + +@item +finish the symbol with the characters @code{@}#}. +@end itemize + +Here are a few examples of this form of read syntax. The first symbol +needs to use extended syntax because it contains a space character, the +second because it contains a line break, and the last because it looks +like a number. + +@lisp +#@{foo bar@}# + +#@{what +ever@}# + +#@{4242@}# +@end lisp + +Although Guile provides this extended read syntax for symbols, +widespread usage of it is discouraged because it is not portable and not +very readable. + + +@node Symbol Uninterned +@subsubsection Uninterned Symbols + +What makes symbols useful is that they are automatically kept unique. +There are no two symbols that are distinct objects but have the same +name. But of course, there is no rule without exception. In addition +to the normal symbols that have been discussed up to now, you can also +create special @dfn{uninterned} symbols that behave slightly +differently. + +To understand what is different about them and why they might be useful, +we look at how normal symbols are actually kept unique. + +Whenever Guile wants to find the symbol with a specific name, for +example during @code{read} or when executing @code{string->symbol}, it +first looks into a table of all existing symbols to find out whether a +symbol with the given name already exists. When this is the case, Guile +just returns that symbol. When not, a new symbol with the name is +created and entered into the table so that it can be found later. + +Sometimes you might want to create a symbol that is guaranteed `fresh', +i.e. a symbol that did not exist previously. You might also want to +somehow guarantee that no one else will ever unintentionally stumble +across your symbol in the future. These properties of a symbol are +often needed when generating code during macro expansion. When +introducing new temporary variables, you want to guarantee that they +don't conflict with variables in other people's code. + +The simplest way to arrange for this is to create a new symbol but +not enter it into the global table of all symbols. That way, no one +will ever get access to your symbol by chance. Symbols that are not in +the table are called @dfn{uninterned}. Of course, symbols that +@emph{are} in the table are called @dfn{interned}. + +You create new uninterned symbols with the function @code{make-symbol}. +You can test whether a symbol is interned or not with +@code{symbol-interned?}. + +Uninterned symbols break the rule that the name of a symbol uniquely +identifies the symbol object. Because of this, they can not be written +out and read back in like interned symbols. Currently, Guile has no +support for reading uninterned symbols. Note that the function +@code{gensym} does not return uninterned symbols for this reason. + +@deffn {Scheme Procedure} make-symbol name +@deffnx {C Function} scm_make_symbol (name) +Return a new uninterned symbol with the name @var{name}. The returned +symbol is guaranteed to be unique and future calls to +@code{string->symbol} will not return it. +@end deffn + +@deffn {Scheme Procedure} symbol-interned? symbol +@deffnx {C Function} scm_symbol_interned_p (symbol) +Return @code{#t} if @var{symbol} is interned, otherwise return +@code{#f}. +@end deffn + +For example: + +@lisp +(define foo-1 (string->symbol "foo")) +(define foo-2 (string->symbol "foo")) +(define foo-3 (make-symbol "foo")) +(define foo-4 (make-symbol "foo")) + +(eq? foo-1 foo-2) +@result{} #t +; Two interned symbols with the same name are the same object, + +(eq? foo-1 foo-3) +@result{} #f +; but a call to make-symbol with the same name returns a +; distinct object. + +(eq? foo-3 foo-4) +@result{} #f +; A call to make-symbol always returns a new object, even for +; the same name. + +foo-3 +@result{} #<uninterned-symbol foo 8085290> +; Uninterned symbols print differently from interned symbols, + +(symbol? foo-3) +@result{} #t +; but they are still symbols, + +(symbol-interned? foo-3) +@result{} #f +; just not interned. +@end lisp + + +@node Keywords +@subsection Keywords +@tpindex Keywords + +Keywords are self-evaluating objects with a convenient read syntax that +makes them easy to type. + +Guile's keyword support conforms to R5RS, and adds a (switchable) read +syntax extension to permit keywords to begin with @code{:} as well as +@code{#:}. + +@menu +* Why Use Keywords?:: Motivation for keyword usage. +* Coding With Keywords:: How to use keywords. +* Keyword Read Syntax:: Read syntax for keywords. +* Keyword Procedures:: Procedures for dealing with keywords. +* Keyword Primitives:: The underlying primitive procedures. +@end menu + +@node Why Use Keywords? +@subsubsection Why Use Keywords? + +Keywords are useful in contexts where a program or procedure wants to be +able to accept a large number of optional arguments without making its +interface unmanageable. + +To illustrate this, consider a hypothetical @code{make-window} +procedure, which creates a new window on the screen for drawing into +using some graphical toolkit. There are many parameters that the caller +might like to specify, but which could also be sensibly defaulted, for +example: + +@itemize @bullet +@item +color depth -- Default: the color depth for the screen + +@item +background color -- Default: white + +@item +width -- Default: 600 + +@item +height -- Default: 400 +@end itemize + +If @code{make-window} did not use keywords, the caller would have to +pass in a value for each possible argument, remembering the correct +argument order and using a special value to indicate the default value +for that argument: + +@lisp +(make-window 'default ;; Color depth + 'default ;; Background color + 800 ;; Width + 100 ;; Height + @dots{}) ;; More make-window arguments +@end lisp + +With keywords, on the other hand, defaulted arguments are omitted, and +non-default arguments are clearly tagged by the appropriate keyword. As +a result, the invocation becomes much clearer: + +@lisp +(make-window #:width 800 #:height 100) +@end lisp + +On the other hand, for a simpler procedure with few arguments, the use +of keywords would be a hindrance rather than a help. The primitive +procedure @code{cons}, for example, would not be improved if it had to +be invoked as + +@lisp +(cons #:car x #:cdr y) +@end lisp + +So the decision whether to use keywords or not is purely pragmatic: use +them if they will clarify the procedure invocation at point of call. + +@node Coding With Keywords +@subsubsection Coding With Keywords + +If a procedure wants to support keywords, it should take a rest argument +and then use whatever means is convenient to extract keywords and their +corresponding arguments from the contents of that rest argument. + +The following example illustrates the principle: the code for +@code{make-window} uses a helper procedure called +@code{get-keyword-value} to extract individual keyword arguments from +the rest argument. + +@lisp +(define (get-keyword-value args keyword default) + (let ((kv (memq keyword args))) + (if (and kv (>= (length kv) 2)) + (cadr kv) + default))) + +(define (make-window . args) + (let ((depth (get-keyword-value args #:depth screen-depth)) + (bg (get-keyword-value args #:bg "white")) + (width (get-keyword-value args #:width 800)) + (height (get-keyword-value args #:height 100)) + @dots{}) + @dots{})) +@end lisp + +But you don't need to write @code{get-keyword-value}. The @code{(ice-9 +optargs)} module provides a set of powerful macros that you can use to +implement keyword-supporting procedures like this: + +@lisp +(use-modules (ice-9 optargs)) + +(define (make-window . args) + (let-keywords args #f ((depth screen-depth) + (bg "white") + (width 800) + (height 100)) + ...)) +@end lisp + +@noindent +Or, even more economically, like this: + +@lisp +(use-modules (ice-9 optargs)) + +(define* (make-window #:key (depth screen-depth) + (bg "white") + (width 800) + (height 100)) + ...) +@end lisp + +For further details on @code{let-keywords}, @code{define*} and other +facilities provided by the @code{(ice-9 optargs)} module, see +@ref{Optional Arguments}. + + +@node Keyword Read Syntax +@subsubsection Keyword Read Syntax + +Guile, by default, only recognizes the keyword syntax specified by R5RS. +A token of the form @code{#:NAME}, where @code{NAME} has the same syntax +as a Scheme symbol (@pxref{Symbol Read Syntax}), is the external +representation of the keyword named @code{NAME}. Keyword objects print +using this syntax as well, so values containing keyword objects can be +read back into Guile. When used in an expression, keywords are +self-quoting objects. + +If the @code{keyword} read option is set to @code{'prefix}, Guile also +recognizes the alternative read syntax @code{:NAME}. Otherwise, tokens +of the form @code{:NAME} are read as symbols, as required by R5RS. + +To enable and disable the alternative non-R5RS keyword syntax, you use +the @code{read-set!} procedure documented in @ref{User level options +interfaces} and @ref{Reader options}. + +@smalllisp +(read-set! keywords 'prefix) + +#:type +@result{} +#:type + +:type +@result{} +#:type + +(read-set! keywords #f) + +#:type +@result{} +#:type + +:type +@print{} +ERROR: In expression :type: +ERROR: Unbound variable: :type +ABORT: (unbound-variable) +@end smalllisp + +@node Keyword Procedures +@subsubsection Keyword Procedures + +The following procedures can be used for converting symbols to keywords +and back. + +@deffn {Scheme Procedure} symbol->keyword sym +Return a keyword with the same characters as in @var{sym}. +@end deffn + +@deffn {Scheme Procedure} keyword->symbol kw +Return a symbol with the same characters as in @var{kw}. +@end deffn + + +@node Keyword Primitives +@subsubsection Keyword Primitives + +Internally, a keyword is implemented as something like a tagged symbol, +where the tag identifies the keyword as being self-evaluating, and the +symbol, known as the keyword's @dfn{dash symbol} has the same name as +the keyword name but prefixed by a single dash. For example, the +keyword @code{#:name} has the corresponding dash symbol @code{-name}. + +Most keyword objects are constructed automatically by the reader when it +reads a token beginning with @code{#:}. However, if you need to +construct a keyword object programmatically, you can do so by calling +@code{make-keyword-from-dash-symbol} with the corresponding dash symbol +(as the reader does). The dash symbol for a keyword object can be +retrieved using the @code{keyword-dash-symbol} procedure. + +@deffn {Scheme Procedure} make-keyword-from-dash-symbol symbol +@deffnx {C Function} scm_make_keyword_from_dash_symbol (symbol) +Make a keyword object from a @var{symbol} that starts with a dash. +For example, + +@example +(make-keyword-from-dash-symbol '-foo) +@result{} #:foo +@end example +@end deffn + +@deffn {Scheme Procedure} keyword? obj +@deffnx {C Function} scm_keyword_p (obj) +Return @code{#t} if the argument @var{obj} is a keyword, else +@code{#f}. +@end deffn + +@deffn {Scheme Procedure} keyword-dash-symbol keyword +@deffnx {C Function} scm_keyword_dash_symbol (keyword) +Return the dash symbol for @var{keyword}. +This is the inverse of @code{make-keyword-from-dash-symbol}. +For example, + +@example +(keyword-dash-symbol #:foo) +@result{} -foo +@end example +@end deffn + +@deftypefn {C Function} SCM scm_c_make_keyword (char *@var{str}) +Make a keyword object from a string. For example, + +@example +scm_c_make_keyword ("foo") +@result{} #:foo +@end example +@c +@c FIXME: What can be said about the string argument? Currently it's +@c not used after creation, but should that be documented? +@end deftypefn + + +@node Other Types +@subsection ``Functionality-Centric'' Data Types + +Procedures and macros are documented in their own chapter: see +@ref{Procedures and Macros}. + +Variable objects are documented as part of the description of Guile's +module system: see @ref{Variables}. + +Asyncs, dynamic roots and fluids are described in the chapter on +scheduling: see @ref{Scheduling}. + +Hooks are documented in the chapter on general utility functions: see +@ref{Hooks}. + +Ports are described in the chapter on I/O: see @ref{Input and Output}. + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/api-debug.texi b/doc/ref/api-debug.texi new file mode 100644 index 000000000..cf4b2800a --- /dev/null +++ b/doc/ref/api-debug.texi @@ -0,0 +1,361 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Debugging +@section Debugging Infrastructure + +@menu +* Interactive Debugging:: Functions intended for interactive use. +* Breakpoints:: +* Source Properties:: Remembering the source of an expression. +* Using Traps:: +* Capturing the Stack or Innermost Stack Frame:: +* Examining the Stack:: +* Examining Stack Frames:: +* Decoding Memoized Source Expressions:: +* Starting a New Stack:: +@end menu + +@node Interactive Debugging +@subsection Interactive Debugging + +@deffn {Scheme Procedure} backtrace +@deffnx {C Function} scm_backtrace () +Display a backtrace of the stack saved by the last error +to the current output port. +@end deffn + +@deffn {Scheme Procedure} debug +Invoke the Guile debugger to explore the context of the last error. +@end deffn + +@node Breakpoints +@subsection Breakpoints + +@deffn {Generic Function} set-breakpoint! behaviour . location-args +Set a breakpoint with behaviour @var{behaviour} at the location +specified by @var{location-args}. + +The form of the @var{location-args} depends upon what methods for +@code{set-breakpoint!} have been provided by the implementations of +subclasses of the @code{<breakpoint>} base class. +@end deffn + +@deffn {Generic Function} get-breakpoint . location-args +Find and return the breakpoint instance at the location specified by +@var{location-args}. + +The form of the @var{location-args} depends upon what methods for +@code{get-breakpoint} have been provided by the implementations of +subclasses of the @code{<breakpoint>} base class. +@end deffn + +@deffn {Method} set-breakpoint! behaviour (proc <procedure>) +Set a breakpoint with behaviour @var{behaviour} before applications of +the procedure @var{proc}. +@end deffn + +@deffn {Method} set-breakpoint! behaviour x-as-read (x-pairified <pair>) +Set a breakpoint with behaviour @var{behaviour} on the source expression +@var{x-pairified}, storing @var{x-as-read} for use in messages +describing the breakpoint. +@end deffn + +@deffn {Method} set-breakpoint! behaviour (number <integer>) +Change the behaviour of existing breakpoint number @var{number} to +@var{behaviour}. +@end deffn + +@deffn {Accessor} bp-behaviour breakpoint +Get or set the behaviour of the breakpoint instance @var{breakpoint}. +@end deffn + +@deffn {Accessor} bp-enabled? breakpoint +Get or set the enabled state of the specified @var{breakpoint}. +@end deffn + +@deffn {Procedure} enable-breakpoint! . location-args +@deffnx {Procedure} disable-breakpoint! . location-args +Enable or disable the breakpoint at the location specified by +@var{location-args}. +@end deffn + +@deffn {Generic Function} bp-delete! breakpoint +Delete breakpoint @var{breakpoint}. This means (1) doing whatever is +needed to prevent the breakpoint from triggering again, and (2) removing +it from the global list of current breakpoints. +@end deffn + +@deffn {Procedure} delete-breakpoint! . location-args +Delete the breakpoint at the location specified by @var{location-args}. +@end deffn + +@deffn {Generic Function} bp-describe breakpoint port +Print a description of @var{breakpoint} to the specified @var{port}. +@var{port} can be @code{#t} for standard output, or else any output +port. +@end deffn + +@deffn {Procedure} describe-breakpoint . location-args +Print (to standard output) a description of the breakpoint at location +specified by @var{location-args}. +@end deffn + +@deffn {Procedure} all-breakpoints +Return a list of all current breakpoints, ordered by breakpoint number. +@end deffn + +@deffn {Procedure} describe-all-breakpoints +Print a description of all current breakpoints to standard output. +@end deffn + + +@node Source Properties +@subsection Source Properties + +@cindex 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 +@dfn{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 @code{(xxx)} and @code{xxx} at the Guile prompt +(where the variable @code{xxx} has not been defined): + +@example +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) +@end example + +@noindent +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'' (@pxref{Reader options}). This option is switched +@emph{on} by default, together with the debug options ``debug'' and +``backtrace'' (@pxref{Debugger options}), when Guile is run +interactively; all these options are @emph{off} by default when Guile +runs a script non-interactively. + + +@node Using Traps +@subsection Using Traps + +@deffn {Scheme Procedure} with-traps thunk +@deffnx {C Function} scm_with_traps (thunk) +Call @var{thunk} with traps enabled. +@end deffn + +@deffn {Scheme Procedure} debug-object? obj +@deffnx {C Function} scm_debug_object_p (obj) +Return @code{#t} if @var{obj} is a debug object. +@end deffn + + +@node Capturing the Stack or Innermost Stack Frame +@subsection Capturing the Stack or Innermost Stack Frame + +When an error occurs in a running program, or the program hits a +breakpoint, its state at that point can be represented by a @dfn{stack} +of all the evaluations and procedure applications that are logically in +progress at that time, each of which is known as a @dfn{frame}. The +programmer can learn more about the program's state at the point of +interruption or error by inspecting the stack and its frames. + +@deffn {Scheme Procedure} make-stack obj . args +@deffnx {C Function} scm_make_stack (obj, args) +Create a new stack. If @var{obj} is @code{#t}, the current +evaluation stack is used for creating the stack frames, +otherwise the frames are taken from @var{obj} (which must be +either a debug object or a continuation). + +@var{args} should be a list containing any combination of +integer, procedure and @code{#t} values. + +These values specify various ways of cutting away uninteresting +stack frames from the top and bottom of the stack that +@code{make-stack} returns. They come in pairs like this: +@code{(@var{inner_cut_1} @var{outer_cut_1} @var{inner_cut_2} +@var{outer_cut_2} @dots{})}. + +Each @var{inner_cut_N} can be @code{#t}, an integer, or a +procedure. @code{#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 @var{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 @var{outer_cut_N} of the last pair is missing, it is +taken as 0. +@end deffn + +@deffn {Scheme Procedure} last-stack-frame obj +@deffnx {C Function} scm_last_stack_frame (obj) +Return a stack which consists of a single frame, which is the +last stack frame for @var{obj}. @var{obj} must be either a +debug object or a continuation. +@end deffn + + +@node Examining the Stack +@subsection Examining the Stack + +@deffn {Scheme Procedure} stack? obj +@deffnx {C Function} scm_stack_p (obj) +Return @code{#t} if @var{obj} is a calling stack. +@end deffn + +@deffn {Scheme Procedure} stack-id stack +@deffnx {C Function} scm_stack_id (stack) +Return the identifier given to @var{stack} by @code{start-stack}. +@end deffn + +@deffn {Scheme Procedure} stack-length stack +@deffnx {C Function} scm_stack_length (stack) +Return the length of @var{stack}. +@end deffn + +@deffn {Scheme Procedure} stack-ref stack index +@deffnx {C Function} scm_stack_ref (stack, index) +Return the @var{index}'th frame from @var{stack}. +@end deffn + +@deffn {Scheme Procedure} display-backtrace stack port [first [depth]] +@deffnx {C Function} scm_display_backtrace (stack, port, first, depth) +Display a backtrace to the output port @var{port}. @var{stack} +is the stack to take the backtrace from, @var{first} specifies +where in the stack to start and @var{depth} how much frames +to display. Both @var{first} and @var{depth} can be @code{#f}, +which means that default values will be used. +@end deffn + + +@node Examining Stack Frames +@subsection Examining Stack Frames + +@deffn {Scheme Procedure} frame? obj +@deffnx {C Function} scm_frame_p (obj) +Return @code{#t} if @var{obj} is a stack frame. +@end deffn + +@deffn {Scheme Procedure} frame-number frame +@deffnx {C Function} scm_frame_number (frame) +Return the frame number of @var{frame}. +@end deffn + +@deffn {Scheme Procedure} frame-previous frame +@deffnx {C Function} scm_frame_previous (frame) +Return the previous frame of @var{frame}, or @code{#f} if +@var{frame} is the first frame in its stack. +@end deffn + +@deffn {Scheme Procedure} frame-next frame +@deffnx {C Function} scm_frame_next (frame) +Return the next frame of @var{frame}, or @code{#f} if +@var{frame} is the last frame in its stack. +@end deffn + +@deffn {Scheme Procedure} frame-source frame +@deffnx {C Function} scm_frame_source (frame) +Return the source of @var{frame}. +@end deffn + +@deffn {Scheme Procedure} frame-procedure? frame +@deffnx {C Function} scm_frame_procedure_p (frame) +Return @code{#t} if a procedure is associated with @var{frame}. +@end deffn + +@deffn {Scheme Procedure} frame-procedure frame +@deffnx {C Function} scm_frame_procedure (frame) +Return the procedure for @var{frame}, or @code{#f} if no +procedure is associated with @var{frame}. +@end deffn + +@deffn {Scheme Procedure} frame-arguments frame +@deffnx {C Function} scm_frame_arguments (frame) +Return the arguments of @var{frame}. +@end deffn + +@deffn {Scheme Procedure} frame-evaluating-args? frame +@deffnx {C Function} scm_frame_evaluating_args_p (frame) +Return @code{#t} if @var{frame} contains evaluated arguments. +@end deffn + +@deffn {Scheme Procedure} frame-overflow? frame +@deffnx {C Function} scm_frame_overflow_p (frame) +Return @code{#t} if @var{frame} is an overflow frame. +@end deffn + +@deffn {Scheme Procedure} frame-real? frame +@deffnx {C Function} scm_frame_real_p (frame) +Return @code{#t} if @var{frame} is a real frame. +@end deffn + +@deffn {Scheme Procedure} display-application frame [port [indent]] +@deffnx {C Function} scm_display_application (frame, port, indent) +Display a procedure application @var{frame} to the output port +@var{port}. @var{indent} specifies the indentation of the +output. +@end deffn + + +@node Decoding Memoized Source Expressions +@subsection Decoding Memoized Source Expressions + +@deffn {Scheme Procedure} memoized? obj +@deffnx {C Function} scm_memoized_p (obj) +Return @code{#t} if @var{obj} is memoized. +@end deffn + +@deffn {Scheme Procedure} unmemoize m +@deffnx {C Function} scm_unmemoize (m) +Unmemoize the memoized expression @var{m}, +@end deffn + +@deffn {Scheme Procedure} memoized-environment m +@deffnx {C Function} scm_memoized_environment (m) +Return the environment of the memoized expression @var{m}. +@end deffn + + +@node Starting a New Stack +@subsection Starting a New Stack + +@deffn {Scheme Syntax} start-stack id exp +Evaluate @var{exp} on a new calling stack with identity @var{id}. If +@var{exp} is interrupted during evaluation, backtraces will not display +frames farther back than @var{exp}'s top-level form. This macro is a +way of artificially limiting backtraces and stack procedures, largely as +a convenience to the user. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/debugging.texi b/doc/ref/api-deprecated.texi index e69de29bb..e69de29bb 100644 --- a/doc/ref/debugging.texi +++ b/doc/ref/api-deprecated.texi diff --git a/doc/ref/api-evaluation.texi b/doc/ref/api-evaluation.texi new file mode 100644 index 000000000..97147235c --- /dev/null +++ b/doc/ref/api-evaluation.texi @@ -0,0 +1,604 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Read/Load/Eval +@section Reading and Evaluating Scheme Code + +This chapter describes Guile functions that are concerned with reading, +loading and evaluating Scheme code at run time. + +@menu +* Scheme Syntax:: Standard and extended Scheme syntax. +* Scheme Read:: Reading Scheme code. +* Fly Evaluation:: Procedures for on the fly evaluation. +* Loading:: Loading Scheme code from file. +* Delayed Evaluation:: Postponing evaluation until it is needed. +* Local Evaluation:: Evaluation in a local environment. +* Evaluator Behaviour:: Modifying Guile's evaluator. +@end menu + + +@node Scheme Syntax +@subsection Scheme Syntax: Standard and Guile Extensions + +@menu +* Expression Syntax:: +* Comments:: +* Block Comments:: +* Case Sensitivity:: +* Keyword Syntax:: +* Reader Extensions:: +@end menu + + +@node Expression Syntax +@subsubsection Expression Syntax + +An expression to be evaluated takes one of the following forms. + +@table @nicode + +@item @var{symbol} +A symbol is evaluated by dereferencing. A binding of that symbol is +sought and the value there used. For example, + +@example +(define x 123) +x @result{} 123 +@end example + +@item (@var{proc} @var{args}@dots{}) +A parenthesised expression is a function call. @var{proc} and each +argument are evaluated, then the function (which @var{proc} evaluated +to) is called with those arguments. + +The order in which @var{proc} and the arguments are evaluated is +unspecified, so be careful when using expressions with side effects. + +@example +(max 1 2 3) @result{} 3 + +(define (get-some-proc) min) +((get-some-proc) 1 2 3) @result{} 1 +@end example + +The same sort of parenthesised form is used for a macro invocation, +but in that case the arguments are not evaluated. See the +descriptions of macros for more on this (@pxref{Macros}, and +@pxref{Syntax Rules}). + +@item @var{constant} +Number, string, character and boolean constants evaluate ``to +themselves'', so can appear as literals. + +@example +123 @result{} 123 +99.9 @result{} 99.9 +"hello" @result{} "hello" +#\z @result{} #\z +#t @result{} #t +@end example + +Note that an application must not attempt to modify literal strings, +since they may be in read-only memory. + +@item (quote @var{data}) +@itemx '@var{data} +@findex quote +@findex ' +Quoting is used to obtain a literal symbol (instead of a variable +reference), a literal list (instead of a function call), or a literal +vector. @nicode{'} is simply a shorthand for a @code{quote} form. +For example, + +@example +'x @result{} x +'(1 2 3) @result{} (1 2 3) +'#(1 (2 3) 4) @result{} #(1 (2 3) 4) +(quote x) @result{} x +(quote (1 2 3)) @result{} (1 2 3) +(quote #(1 (2 3) 4)) @result{} #(1 (2 3) 4) +@end example + +Note that an application must not attempt to modify literal lists or +vectors obtained from a @code{quote} form, since they may be in +read-only memory. + +@item (quasiquote @var{data}) +@itemx `@var{data} +@findex quasiquote +@findex ` +Backquote quasi-quotation is like @code{quote}, but selected +sub-expressions are evaluated. This is a convenient way to construct +a list or vector structure most of which is constant, but at certain +points should have expressions substituted. + +The same effect can always be had with suitable @code{list}, +@code{cons} or @code{vector} calls, but quasi-quoting is often easier. + +@table @nicode + +@item (unquote @var{expr}) +@itemx ,@var{expr} +@findex unquote +@findex , +Within the quasiquote @var{data}, @code{unquote} or @code{,} indicates +an expression to be evaluated and inserted. The comma syntax @code{,} +is simply a shorthand for an @code{unquote} form. For example, + +@example +`(1 2 ,(* 9 9) 3 4) @result{} (1 2 81 3 4) +`(1 (unquote (+ 1 1)) 3) @result{} (1 2 3) +`#(1 ,(/ 12 2)) @result{} #(1 6) +@end example + +@item (unquote-splicing @var{expr}) +@itemx ,@@@var{expr} +@findex unquote-splicing +@findex ,@@ +Within the quasiquote @var{data}, @code{unquote-splicing} or +@code{,@@} indicates an expression to be evaluated and the elements of +the returned list inserted. @var{expr} must evaluate to a list. The +``comma-at'' syntax @code{,@@} is simply a shorthand for an +@code{unquote-splicing} form. + +@example +(define x '(2 3)) +`(1 ,@@x 4) @result{} (1 2 3 4) +`(1 (unquote-splicing (map 1+ x))) @result{} (1 3 4) +`#(9 ,@@x 9) @result{} #(9 2 3 9) +@end example + +Notice @code{,@@} differs from plain @code{,} in the way one level of +nesting is stripped. For @code{,@@} the elements of a returned list +are inserted, whereas with @code{,} it would be the list itself +inserted. +@end table + +@c +@c FIXME: What can we say about the mutability of a quasiquote +@c result? R5RS doesn't seem to specify anything, though where it +@c says backquote without commas is the same as plain quote then +@c presumably the "fixed" portions of a quasiquote expression must be +@c treated as immutable. +@c + +@end table + + +@node Comments +@subsubsection Comments + +@c FIXME::martin: Review me! + +Comments in Scheme source files are written by starting them with a +semicolon character (@code{;}). The comment then reaches up to the end +of the line. Comments can begin at any column, and the may be inserted +on the same line as Scheme code. + +@lisp +; Comment +;; Comment too +(define x 1) ; Comment after expression +(let ((y 1)) + ;; Display something. + (display y) +;;; Comment at left margin. + (display (+ y 1))) +@end lisp + +It is common to use a single semicolon for comments following +expressions on a line, to use two semicolons for comments which are +indented like code, and three semicolons for comments which start at +column 0, even if they are inside an indented code block. This +convention is used when indenting code in Emacs' Scheme mode. + + +@node Block Comments +@subsubsection Block Comments + +@c FIXME::martin: Review me! + +@cindex multiline comments +In addition to the standard line comments defined by R5RS, Guile has +another comment type for multiline comments, called @dfn{block +comments}. This type of comment begins with the character sequence +@code{#!} and ends with the characters @code{!#}, which must appear on a +line of their own. These comments are compatible with the block +comments in the Scheme Shell @file{scsh} (@pxref{The Scheme shell +(scsh)}). The characters @code{#!} were chosen because they are the +magic characters used in shell scripts for indicating that the name of +the program for executing the script follows on the same line. + +Thus a Guile script often starts like this. + +@lisp +#! /usr/local/bin/guile -s +!# +@end lisp + +More details on Guile scripting can be found in the scripting section +(@pxref{Guile Scripting}). + + +@node Case Sensitivity +@subsubsection Case Sensitivity + +@c FIXME::martin: Review me! + +Scheme as defined in R5RS is not case sensitive when reading symbols. +Guile, on the contrary is case sensitive by default, so the identifiers + +@lisp +guile-whuzzy +Guile-Whuzzy +@end lisp + +are the same in R5RS Scheme, but are different in Guile. + +It is possible to turn off case sensitivity in Guile by setting the +reader option @code{case-insensitive}. More on reader options can be +found at (@pxref{Reader options}). + +@lisp +(read-enable 'case-insensitive) +@end lisp + +Note that this is seldom a problem, because Scheme programmers tend not +to use uppercase letters in their identifiers anyway. + + +@node Keyword Syntax +@subsubsection Keyword Syntax + + +@node Reader Extensions +@subsubsection Reader Extensions + +@deffn {Scheme Procedure} read-hash-extend chr proc +@deffnx {C Function} scm_read_hash_extend (chr, proc) +Install the procedure @var{proc} for reading expressions +starting with the character sequence @code{#} and @var{chr}. +@var{proc} will be called with two arguments: the character +@var{chr} and the port to read further data from. The object +returned will be the return value of @code{read}. +@end deffn + + +@node Scheme Read +@subsection Reading Scheme Code + +@rnindex read +@deffn {Scheme Procedure} read [port] +@deffnx {C Function} scm_read (port) +Read an s-expression from the input port @var{port}, or from +the current input port if @var{port} is not specified. +Any whitespace before the next token is discarded. +@end deffn + +The behaviour of Guile's Scheme reader can be modified by manipulating +its read options. For more information about options, @xref{User level +options interfaces}. If you want to know which reader options are +available, @xref{Reader options}. + +@c FIXME::martin: This is taken from libguile/options.c. Is there +@c actually a difference between 'help and 'full? + +@deffn {Scheme Procedure} read-options [setting] +Display the current settings of the read options. If @var{setting} is +omitted, only a short form of the current read options is printed. +Otherwise, @var{setting} should be one of the following symbols: +@table @code +@item help +Display the complete option settings. +@item full +Like @code{help}, but also print programmer options. +@end table +@end deffn + +@deffn {Scheme Procedure} read-enable option-name +@deffnx {Scheme Procedure} read-disable option-name +@deffnx {Scheme Procedure} read-set! option-name value +Modify the read options. @code{read-enable} should be used with boolean +options and switches them on, @code{read-disable} switches them off. +@code{read-set!} can be used to set an option to a specific value. +@end deffn + +@deffn {Scheme Procedure} read-options-interface [setting] +@deffnx {C Function} scm_read_options (setting) +Option interface for the read options. Instead of using +this procedure directly, use the procedures @code{read-enable}, +@code{read-disable}, @code{read-set!} and @code{read-options}. +@end deffn + + +@node Fly Evaluation +@subsection Procedures for On the Fly Evaluation + +@xref{Environments}. + +@rnindex eval +@c ARGFIXME environment/environment specifier +@deffn {Scheme Procedure} eval exp module +@deffnx {C Function} scm_eval (exp, module) +Evaluate @var{exp}, a list representing a Scheme expression, +in the top-level environment specified by @var{module}. +While @var{exp} is evaluated (using @code{primitive-eval}), +@var{module} is made the current module. The current module +is reset to its previous value when @var{eval} returns. +@end deffn + +@rnindex interaction-environment +@deffn {Scheme Procedure} interaction-environment +@deffnx {C Function} scm_interaction_environment () +Return a specifier for the environment that contains +implementation--defined bindings, typically a superset of those +listed in the report. The intent is that this procedure will +return the environment in which the implementation would +evaluate expressions dynamically typed by the user. +@end deffn + +@deffn {Scheme Procedure} eval-string string [module] +@deffnx {C Function} scm_eval_string (string) +@deffnx {C Function} scm_eval_string_in_module (string, module) +Evaluate @var{string} as the text representation of a Scheme form or +forms, and return whatever value they produce. Evaluation takes place +in the given module, or in the current module when no module is given. +While the code is evaluated, the given module is made the current one. +The current module is restored when this procedure returns. +@end deffn + +@deffn {Scheme Procedure} apply proc arg1 @dots{} argN arglst +@deffnx {C Function} scm_apply_0 (proc, arglst) +@deffnx {C Function} scm_apply_1 (proc, arg1, arglst) +@deffnx {C Function} scm_apply_2 (proc, arg1, arg2, arglst) +@deffnx {C Function} scm_apply_3 (proc, arg1, arg2, arg3, arglst) +@deffnx {C Function} scm_apply (proc, arg, rest) +@rnindex apply +Call @var{proc} with arguments @var{arg1} @dots{} @var{argN} plus the +elements of the @var{arglst} list. + +@code{scm_apply} takes parameters corresponding to a Scheme level +@code{(lambda (proc arg . rest) ...)}. So @var{arg} and all but the +last element of the @var{rest} list make up +@var{arg1}@dots{}@var{argN} and the last element of @var{rest} is the +@var{arglst} list. Or if @var{rest} is the empty list @code{SCM_EOL} +then there's no @var{arg1}@dots{}@var{argN} and @var{arg} is the +@var{arglst}. + +@var{arglst} is not modified, but the @var{rest} list passed to +@code{scm_apply} is modified. +@end deffn + +@deffn {C Function} scm_call_0 (proc) +@deffnx {C Function} scm_call_1 (proc, arg1) +@deffnx {C Function} scm_call_2 (proc, arg1, arg2) +@deffnx {C Function} scm_call_3 (proc, arg1, arg2, arg3) +Call @var{proc} with the given arguments. +@end deffn + +@deffn {Scheme Procedure} apply:nconc2last lst +@deffnx {C Function} scm_nconc2last (lst) +@var{lst} should be a list (@var{arg1} @dots{} @var{argN} +@var{arglst}), with @var{arglst} being a list. This function returns +a list comprising @var{arg1} to @var{argN} plus the elements of +@var{arglst}. @var{lst} is modified to form the return. @var{arglst} +is not modified, though the return does share structure with it. + +This operation collects up the arguments from a list which is +@code{apply} style parameters. +@end deffn + +@deffn {Scheme Procedure} primitive-eval exp +@deffnx {C Function} scm_primitive_eval (exp) +Evaluate @var{exp} in the top-level environment specified by +the current module. +@end deffn + + +@node Loading +@subsection Loading Scheme Code from File + +@rnindex load +@deffn {Scheme Procedure} load filename +Load @var{filename} and evaluate its contents in the top-level +environment. The load paths are not searched. If the variable +@code{%load-hook} is defined, it should be bound to a procedure that +will be called before any code is loaded. See documentation for +@code{%load-hook} later in this section. +@end deffn + +@deffn {Scheme Procedure} load-from-path filename +Similar to @code{load}, but searches for @var{filename} in the load +paths. +@end deffn + +@deffn {Scheme Procedure} primitive-load filename +@deffnx {C Function} scm_primitive_load (filename) +Load the file named @var{filename} and evaluate its contents in +the top-level environment. The load paths are not searched; +@var{filename} must either be a full pathname or be a pathname +relative to the current directory. If the variable +@code{%load-hook} is defined, it should be bound to a procedure +that will be called before any code is loaded. See the +documentation for @code{%load-hook} later in this section. +@end deffn + +@deffn {Scheme Procedure} primitive-load-path filename +@deffnx {C Function} scm_primitive_load_path (filename) +Search @var{%load-path} for the file named @var{filename} and +load it into the top-level environment. If @var{filename} is a +relative pathname and is not found in the list of search paths, +an error is signalled. +@end deffn + +@deffn {Scheme Procedure} %search-load-path filename +@deffnx {C Function} scm_sys_search_load_path (filename) +Search @var{%load-path} for the file named @var{filename}, +which must be readable by the current user. If @var{filename} +is found in the list of paths to search or is an absolute +pathname, return its full pathname. Otherwise, return +@code{#f}. Filenames may have any of the optional extensions +in the @code{%load-extensions} list; @code{%search-load-path} +will try each extension automatically. +@end deffn + +@defvar %load-hook +A procedure to be run whenever @code{primitive-load} is called. If this +procedure is defined, it will be called with the filename argument that +was passed to @code{primitive-load}. + +@example +(define %load-hook (lambda (file) + (display "Loading ") + (display file) + (write-line "...."))) @result{} undefined +(load-from-path "foo.scm") +@print{} Loading /usr/local/share/guile/site/foo.scm.... +@end example + +@end defvar + +@deffn {Scheme Procedure} current-load-port +@deffnx {C Function} scm_current_load_port () +Return the current-load-port. +The load port is used internally by @code{primitive-load}. +@end deffn + +@defvar %load-extensions +A list of default file extensions for files containing Scheme code. +@code{%search-load-path} tries each of these extensions when looking for +a file to load. By default, @code{%load-extensions} is bound to the +list @code{("" ".scm")}. +@end defvar + + +@node Delayed Evaluation +@subsection Delayed Evaluation +@cindex delayed evaluation +@cindex promises + +Promises are a convenient way to defer a calculation until its result +is actually needed, and to run such a calculation only once. + +@deffn syntax delay expr +@rnindex delay +Return a promise object which holds the given @var{expr} expression, +ready to be evaluated by a later @code{force}. +@end deffn + +@deffn {Scheme Procedure} promise? obj +@deffnx {C Function} scm_promise_p (obj) +Return true if @var{obj} is a promise. +@end deffn + +@rnindex force +@deffn {Scheme Procedure} force p +@deffnx {C Function} scm_force (p) +Return the value obtained from evaluating the @var{expr} in the given +promise @var{p}. If @var{p} has previously been forced then its +@var{expr} is not evaluated again, instead the value obtained at that +time is simply returned. + +During a @code{force}, an @var{expr} can call @code{force} again on +its own promise, resulting in a recursive evaluation of that +@var{expr}. The first evaluation to return gives the value for the +promise. Higher evaluations run to completion in the normal way, but +their results are ignored, @code{force} always returns the first +value. +@end deffn + + +@node Local Evaluation +@subsection Local Evaluation + +[the-environment] + +@deffn {Scheme Procedure} local-eval exp [env] +@deffnx {C Function} scm_local_eval (exp, env) +Evaluate @var{exp} in its environment. If @var{env} is supplied, +it is the environment in which to evaluate @var{exp}. Otherwise, +@var{exp} must be a memoized code object (in which case, its environment +is implicit). +@end deffn + + +@node Evaluator Behaviour +@subsection Evaluator Behaviour + +@c FIXME::martin: Maybe this node name is bad, but the old name clashed with +@c `Evaluator options' under `Options and Config'. + +The behaviour of Guile's evaluator can be modified by manipulating the +evaluator options. For more information about options, @xref{User level +options interfaces}. If you want to know which evaluator options are +available, @xref{Evaluator options}. + +@c FIXME::martin: This is taken from libguile/options.c. Is there +@c actually a difference between 'help and 'full? + +@deffn {Scheme Procedure} eval-options [setting] +Display the current settings of the evaluator options. If @var{setting} +is omitted, only a short form of the current evaluator options is +printed. Otherwise, @var{setting} should be one of the following +symbols: +@table @code +@item help +Display the complete option settings. +@item full +Like @code{help}, but also print programmer options. +@end table +@end deffn + +@deffn {Scheme Procedure} eval-enable option-name +@deffnx {Scheme Procedure} eval-disable option-name +@deffnx {Scheme Procedure} eval-set! option-name value +Modify the evaluator options. @code{eval-enable} should be used with boolean +options and switches them on, @code{eval-disable} switches them off. +@code{eval-set!} can be used to set an option to a specific value. +@end deffn + +@deffn {Scheme Procedure} eval-options-interface [setting] +@deffnx {C Function} scm_eval_options_interface (setting) +Option interface for the evaluation options. Instead of using +this procedure directly, use the procedures @code{eval-enable}, +@code{eval-disable}, @code{eval-set!} and @code{eval-options}. +@end deffn + +@c FIXME::martin: Why aren't these procedure named like the other options +@c procedures? + +@deffn {Scheme Procedure} traps [setting] +Display the current settings of the evaluator traps options. If +@var{setting} is omitted, only a short form of the current evaluator +traps options is printed. Otherwise, @var{setting} should be one of the +following symbols: +@table @code +@item help +Display the complete option settings. +@item full +Like @code{help}, but also print programmer options. +@end table +@end deffn + +@deffn {Scheme Procedure} trap-enable option-name +@deffnx {Scheme Procedure} trap-disable option-name +@deffnx {Scheme Procedure} trap-set! option-name value +Modify the evaluator options. @code{trap-enable} should be used with boolean +options and switches them on, @code{trap-disable} switches them off. +@code{trap-set!} can be used to set an option to a specific value. +@end deffn + +@deffn {Scheme Procedure} evaluator-traps-interface [setting] +@deffnx {C Function} scm_evaluator_traps (setting) +Option interface for the evaluator trap options. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/api-init.texi b/doc/ref/api-init.texi new file mode 100644 index 000000000..94407114b --- /dev/null +++ b/doc/ref/api-init.texi @@ -0,0 +1,66 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + + +@node Initialization +@section Initializing Guile + +@deftypefn {C Function} void scm_boot_guile (int @var{argc}, char **@var{argv}, void (*@var{main_func}) (void *@var{data}, int @var{argc}, char **@var{argv}), void *@var{data}) +Initialize the Guile Scheme interpreter. Then call @var{main_func}, +passing it @var{data}, @var{argc}, and @var{argv} as indicated. The +function @var{main_func} should do all the work of the program +(initializing other packages, defining application-specific functions, +reading user input, and so on) before returning. When @var{main_func} +returns, @code{scm_boot_guile} calls @code{exit (0)}; +@code{scm_boot_guile} never returns. If you want some other exit +value, have @var{main_func} call @code{exit} itself. + +@code{scm_boot_guile} arranges for the Scheme @code{command-line} +function to return the strings given by @var{argc} and @var{argv}. If +@var{main_func} modifies @var{argc} or @var{argv}, it should call +@code{scm_set_program_arguments} with the final list, so Scheme code +will know which arguments have been processed. + +Why must the caller do all the real work from @var{main_func}? Guile's +garbage collector scans the stack to find all local variables that +reference Scheme objects. To do this, it needs to know the bounds of +the stack that might contain such references. Because there is no +portable way in C to find the base of the stack, @code{scm_boot_guile} +assumes that all references are above its own stack frame. If you try +to manipulate Scheme objects after this function returns, it's the luck +of the draw whether Guile's storage manager will be able to find the +objects you allocate. So, @code{scm_boot_guile} function exits, rather +than returning, to discourage you from making that mistake. + +See @code{scm_init_guile}, below, for a function that can find the real +base of the stack, but not in a portable way. +@end deftypefn + +@deftypefn {C Function} void scm_init_guile () +Initialize the Guile Scheme interpreter. + +In contrast to @code{scm_boot_guile}, this function knows how to find +the true base of the stack and thus does not need to usurp the control +flow of your program. However, since finding the stack base can not be +done portably, this function might not be available in all installations +of Guile. If you can, you should use @code{scm_boot_guile} instead. + +Note that @code{scm_init_guile} does not inform Guile about the command +line arguments that should be returned by the Scheme function +@code{command-line}. You can use @code{scm_set_program_arguments} to do +this. +@end deftypefn + +@deftypefn {C Function} void scm_shell (int @var{argc}, char **@var{argv}) +Process command-line arguments in the manner of the @code{guile} +executable. This includes loading the normal Guile initialization +files, interacting with the user or running any scripts or expressions +specified by @code{-s} or @code{-e} options, and then exiting. +@xref{Invoking Guile}, for more details. + +Since this function does not return, you must do all +application-specific initialization before calling this function. +@end deftypefn diff --git a/doc/ref/api-io.texi b/doc/ref/api-io.texi new file mode 100644 index 000000000..f8611d4d1 --- /dev/null +++ b/doc/ref/api-io.texi @@ -0,0 +1,1161 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Input and Output +@section Input and Output + +@menu +* Ports:: The idea of the port abstraction. +* Reading:: Procedures for reading from a port. +* Writing:: Procedures for writing to a port. +* Closing:: Procedures to close a port. +* Random Access:: Moving around a random access port. +* Line/Delimited:: Read and write lines or delimited text. +* Block Reading and Writing:: Reading and writing blocks of text. +* Default Ports:: Defaults for input, output and errors. +* Port Types:: Types of port and how to make them. +* I/O Extensions:: Using and extending ports in C. +@end menu + + +@node Ports +@subsection Ports + +Sequential input/output in Scheme is represented by operations on a +@dfn{port}. This chapter explains the operations that Guile provides +for working with ports. + +Ports are created by opening, for instance @code{open-file} for a file +(@pxref{File Ports}). Characters can be read from an input port and +written to an output port, or both on an input/output port. A port +can be closed (@pxref{Closing}) when no longer required, after which +any attempt to read or write is an error. + +The formal definition of a port is very generic: an input port is +simply ``an object which can deliver characters on demand,'' and an +output port is ``an object which can accept characters.'' Because +this definition is so loose, it is easy to write functions that +simulate ports in software. @dfn{Soft ports} and @dfn{string ports} +are two interesting and powerful examples of this technique. +(@pxref{Soft Ports}, and @ref{String Ports}.) + +Ports are garbage collected in the usual way (@pxref{Memory +Management}), and will be closed at that time if not already closed. +In this case any errors occuring in the close will not be reported. +Usually a program will want to explicitly close so as to be sure all +its operations have been successful. Of course if a program has +abandoned something due to an error or other condition then closing +problems are probably not of interest. + +It is strongly recommended that file ports be closed explicitly when +no longer required. Most systems have limits on how many files can be +open, both on a per-process and a system-wide basis. A program that +uses many files should take care not to hit those limits. The same +applies to similar system resources such as pipes and sockets. + +Note that automatic garbage collection is triggered only by memory +consumption, not by file or other resource usage, so a program cannot +rely on that to keep it away from system limits. An explicit call to +@code{gc} can of course be relied on to pick up unreferenced ports. +If program flow makes it hard to be certain when to close then this +may be an acceptable way to control resource usage. + +@rnindex input-port? +@deffn {Scheme Procedure} input-port? x +@deffnx {C Function} scm_input_port_p (x) +Return @code{#t} if @var{x} is an input port, otherwise return +@code{#f}. Any object satisfying this predicate also satisfies +@code{port?}. +@end deffn + +@rnindex output-port? +@deffn {Scheme Procedure} output-port? x +@deffnx {C Function} scm_output_port_p (x) +Return @code{#t} if @var{x} is an output port, otherwise return +@code{#f}. Any object satisfying this predicate also satisfies +@code{port?}. +@end deffn + +@deffn {Scheme Procedure} port? x +@deffnx {C Function} scm_port_p (x) +Return a boolean indicating whether @var{x} is a port. +Equivalent to @code{(or (input-port? @var{x}) (output-port? +@var{x}))}. +@end deffn + + +@node Reading +@subsection Reading + +[Generic procedures for reading from ports.] + +@rnindex eof-object? +@deffn {Scheme Procedure} eof-object? x +@deffnx {C Function} scm_eof_object_p (x) +Return @code{#t} if @var{x} is an end-of-file object; otherwise +return @code{#f}. +@end deffn + +@rnindex char-ready? +@deffn {Scheme Procedure} char-ready? [port] +@deffnx {C Function} scm_char_ready_p (port) +Return @code{#t} if a character is ready on input @var{port} +and return @code{#f} otherwise. If @code{char-ready?} returns +@code{#t} then the next @code{read-char} operation on +@var{port} is guaranteed not to hang. If @var{port} is a file +port at end of file then @code{char-ready?} returns @code{#t}. +@footnote{@code{char-ready?} exists to make it possible for a +program to accept characters from interactive ports without +getting stuck waiting for input. Any input editors associated +with such ports must make sure that characters whose existence +has been asserted by @code{char-ready?} cannot be rubbed out. +If @code{char-ready?} were to return @code{#f} at end of file, +a port at end of file would be indistinguishable from an +interactive port that has no ready characters.} +@end deffn + +@rnindex read-char +@deffn {Scheme Procedure} read-char [port] +@deffnx {C Function} scm_read_char (port) +Return the next character available from @var{port}, updating +@var{port} to point to the following character. If no more +characters are available, the end-of-file object is returned. +@end deffn + +@deftypefn {C Function} size_t scm_c_read (SCM port, void *buffer, size_t size) +Read up to @var{size} bytes from @var{port} and store them in +@var{buffer}. The return value is the number of bytes actually read, +which can be less than @var{size} if end-of-file has been reached. + +Note that this function does not update @code{port-line} and +@code{port-column} below. +@end deftypefn + +@rnindex peek-char +@deffn {Scheme Procedure} peek-char [port] +@deffnx {C Function} scm_peek_char (port) +Return the next character available from @var{port}, +@emph{without} updating @var{port} to point to the following +character. If no more characters are available, the +end-of-file object is returned.@footnote{The value returned by +a call to @code{peek-char} is the same as the value that would +have been returned by a call to @code{read-char} on the same +port. The only difference is that the very next call to +@code{read-char} or @code{peek-char} on that @var{port} will +return the value returned by the preceding call to +@code{peek-char}. In particular, a call to @code{peek-char} on +an interactive port will hang waiting for input whenever a call +to @code{read-char} would have hung.} +@end deffn + +@deffn {Scheme Procedure} unread-char cobj [port] +@deffnx {C Function} scm_unread_char (cobj, port) +Place @var{char} in @var{port} so that it will be read by the +next read operation. If called multiple times, the unread characters +will be read again in last-in first-out order. If @var{port} is +not supplied, the current input port is used. +@end deffn + +@deffn {Scheme Procedure} unread-string str port +@deffnx {C Function} scm_unread_string (str, port) +Place the string @var{str} in @var{port} so that its characters will +be read from left-to-right as the next characters from @var{port} +during subsequent read operations. If called multiple times, the +unread characters will be read again in last-in first-out order. If +@var{port} is not supplied, the current-input-port is used. +@end deffn + +@deffn {Scheme Procedure} drain-input port +@deffnx {C Function} scm_drain_input (port) +This procedure clears a port's input buffers, similar +to the way that force-output clears the output buffer. The +contents of the buffers are returned as a single string, e.g., + +@lisp +(define p (open-input-file ...)) +(drain-input p) => empty string, nothing buffered yet. +(unread-char (read-char p) p) +(drain-input p) => initial chars from p, up to the buffer size. +@end lisp + +Draining the buffers may be useful for cleanly finishing +buffered I/O so that the file descriptor can be used directly +for further input. +@end deffn + +@deffn {Scheme Procedure} port-column port +@deffnx {Scheme Procedure} port-line port +@deffnx {C Function} scm_port_column (port) +@deffnx {C Function} scm_port_line (port) +Return the current column number or line number of @var{port}. +If the number is +unknown, the result is #f. Otherwise, the result is a 0-origin integer +- i.e.@: the first character of the first line is line 0, column 0. +(However, when you display a file position, for example in an error +message, we recommend you add 1 to get 1-origin integers. This is +because lines and column numbers traditionally start with 1, and that is +what non-programmers will find most natural.) +@end deffn + +@deffn {Scheme Procedure} set-port-column! port column +@deffnx {Scheme Procedure} set-port-line! port line +@deffnx {C Function} scm_set_port_column_x (port, column) +@deffnx {C Function} scm_set_port_line_x (port, line) +Set the current column or line number of @var{port}. +@end deffn + +@node Writing +@subsection Writing + +[Generic procedures for writing to ports.] + +@deffn {Scheme Procedure} get-print-state port +@deffnx {C Function} scm_get_print_state (port) +Return the print state of the port @var{port}. If @var{port} +has no associated print state, @code{#f} is returned. +@end deffn + +@rnindex write +@deffn {Scheme Procedure} write obj [port] +Send a representation of @var{obj} to @var{port} or to the current +output port if not given. + +The output is designed to be machine readable, and can be read back +with @code{read} (@pxref{Reading}). Strings are printed in +doublequotes, with escapes if necessary, and characters are printed in +@samp{#\} notation. +@end deffn + +@rnindex display +@deffn {Scheme Procedure} display obj [port] +Send a representation of @var{obj} to @var{port} or to the current +output port if not given. + +The output is designed for human readability, it differs from +@code{write} in that strings are printed without doublequotes and +escapes, and characters are printed as per @code{write-char}, not in +@samp{#\} form. +@end deffn + +@rnindex newline +@deffn {Scheme Procedure} newline [port] +@deffnx {C Function} scm_newline (port) +Send a newline to @var{port}. +If @var{port} is omitted, send to the current output port. +@end deffn + +@deffn {Scheme Procedure} port-with-print-state port pstate +@deffnx {C Function} scm_port_with_print_state (port, pstate) +Create a new port which behaves like @var{port}, but with an +included print state @var{pstate}. +@end deffn + +@deffn {Scheme Procedure} print-options-interface [setting] +@deffnx {C Function} scm_print_options (setting) +Option interface for the print options. Instead of using +this procedure directly, use the procedures +@code{print-enable}, @code{print-disable}, @code{print-set!} +and @code{print-options}. +@end deffn + +@deffn {Scheme Procedure} simple-format destination message . args +@deffnx {C Function} scm_simple_format (destination, message, args) +Write @var{message} to @var{destination}, defaulting to +the current output port. +@var{message} can contain @code{~A} (was @code{%s}) and +@code{~S} (was @code{%S}) escapes. When printed, +the escapes are replaced with corresponding members of +@var{ARGS}: +@code{~A} formats using @code{display} and @code{~S} formats +using @code{write}. +If @var{destination} is @code{#t}, then use the current output +port, if @var{destination} is @code{#f}, then return a string +containing the formatted text. Does not add a trailing newline. +@end deffn + +@rnindex write-char +@deffn {Scheme Procedure} write-char chr [port] +@deffnx {C Function} scm_write_char (chr, port) +Send character @var{chr} to @var{port}. +@end deffn + +@deftypefn {C Function} void scm_c_write (SCM port, const void *buffer, size_t size) +Write @var{size} bytes at @var{buffer} to @var{port}. + +Note that this function does not update @code{port-line} and +@code{port-column} (@pxref{Reading}). +@end deftypefn + +@findex fflush +@deffn {Scheme Procedure} force-output [port] +@deffnx {C Function} scm_force_output (port) +Flush the specified output port, or the current output port if @var{port} +is omitted. The current output buffer contents are passed to the +underlying port implementation (e.g., in the case of fports, the +data will be written to the file and the output buffer will be cleared.) +It has no effect on an unbuffered port. + +The return value is unspecified. +@end deffn + +@deffn {Scheme Procedure} flush-all-ports +@deffnx {C Function} scm_flush_all_ports () +Equivalent to calling @code{force-output} on +all open output ports. The return value is unspecified. +@end deffn + + +@node Closing +@subsection Closing + +@deffn {Scheme Procedure} close-port port +@deffnx {C Function} scm_close_port (port) +Close the specified port object. Return @code{#t} if it +successfully closes a port or @code{#f} if it was already +closed. An exception may be raised if an error occurs, for +example when flushing buffered output. See also @ref{Ports and +File Descriptors, close}, for a procedure which can close file +descriptors. +@end deffn + +@deffn {Scheme Procedure} close-input-port port +@deffnx {Scheme Procedure} close-output-port port +@deffnx {C Function} scm_close_input_port (port) +@deffnx {C Function} scm_close_output_port (port) +@rnindex close-input-port +@rnindex close-output-port +Close the specified input or output @var{port}. An exception may be +raised if an error occurs while closing. If @var{port} is already +closed, nothing is done. The return value is unspecified. + +See also @ref{Ports and File Descriptors, close}, for a procedure +which can close file descriptors. +@end deffn + +@deffn {Scheme Procedure} port-closed? port +@deffnx {C Function} scm_port_closed_p (port) +Return @code{#t} if @var{port} is closed or @code{#f} if it is +open. +@end deffn + + +@node Random Access +@subsection Random Access + +@deffn {Scheme Procedure} seek fd_port offset whence +@deffnx {C Function} scm_seek (fd_port, offset, whence) +Sets the current position of @var{fd/port} to the integer +@var{offset}, which is interpreted according to the value of +@var{whence}. + +One of the following variables should be supplied for +@var{whence}: +@defvar SEEK_SET +Seek from the beginning of the file. +@end defvar +@defvar SEEK_CUR +Seek from the current position. +@end defvar +@defvar SEEK_END +Seek from the end of the file. +@end defvar +If @var{fd/port} is a file descriptor, the underlying system +call is @code{lseek}. @var{port} may be a string port. + +The value returned is the new position in the file. This means +that the current position of a port can be obtained using: +@lisp +(seek port 0 SEEK_CUR) +@end lisp +@end deffn + +@deffn {Scheme Procedure} ftell fd_port +@deffnx {C Function} scm_ftell (fd_port) +Return an integer representing the current position of +@var{fd/port}, measured from the beginning. Equivalent to: + +@lisp +(seek port 0 SEEK_CUR) +@end lisp +@end deffn + +@findex truncate +@findex ftruncate +@deffn {Scheme Procedure} truncate-file object [length] +@deffnx {C Function} scm_truncate_file (object, length) +Truncates the object referred to by @var{object} to at most +@var{length} bytes. @var{object} can be a string containing a +file name or an integer file descriptor or a port. +@var{length} may be omitted if @var{object} is not a file name, +in which case the truncation occurs at the current port. +position. The return value is unspecified. +@end deffn + +@node Line/Delimited +@subsection Line Oriented and Delimited Text + +The delimited-I/O module can be accessed with: + +@smalllisp +(use-modules (ice-9 rdelim)) +@end smalllisp + +It can be used to read or write lines of text, or read text delimited by +a specified set of characters. It's similar to the @code{(scsh rdelim)} +module from guile-scsh, but does not use multiple values or character +sets and has an extra procedure @code{write-line}. + +@c begin (scm-doc-string "rdelim.scm" "read-line") +@deffn {Scheme Procedure} read-line [port] [handle-delim] +Return a line of text from @var{port} if specified, otherwise from the +value returned by @code{(current-input-port)}. Under Unix, a line of text +is terminated by the first end-of-line character or by end-of-file. + +If @var{handle-delim} is specified, it should be one of the following +symbols: +@table @code +@item trim +Discard the terminating delimiter. This is the default, but it will +be impossible to tell whether the read terminated with a delimiter or +end-of-file. +@item concat +Append the terminating delimiter (if any) to the returned string. +@item peek +Push the terminating delimiter (if any) back on to the port. +@item split +Return a pair containing the string read from the port and the +terminating delimiter or end-of-file object. +@end table +@end deffn + +@c begin (scm-doc-string "rdelim.scm" "read-line!") +@deffn {Scheme Procedure} read-line! buf [port] +Read a line of text into the supplied string @var{buf} and return the +number of characters added to @var{buf}. If @var{buf} is filled, then +@code{#f} is returned. +Read from @var{port} if +specified, otherwise from the value returned by @code{(current-input-port)}. +@end deffn + +@c begin (scm-doc-string "rdelim.scm" "read-delimited") +@deffn {Scheme Procedure} read-delimited delims [port] [handle-delim] +Read text until one of the characters in the string @var{delims} is found +or end-of-file is reached. Read from @var{port} if supplied, otherwise +from the value returned by @code{(current-input-port)}. +@var{handle-delim} takes the same values as described for @code{read-line}. +@end deffn + +@c begin (scm-doc-string "rdelim.scm" "read-delimited!") +@deffn {Scheme Procedure} read-delimited! delims buf [port] [handle-delim] [start] [end] +Read text into the supplied string @var{buf} and return the number of +characters added to @var{buf} (subject to @var{handle-delim}, which takes +the same values specified for @code{read-line}. If @var{buf} is filled, +@code{#f} is returned for both the number of characters read and the +delimiter. Also terminates if one of the characters in the string +@var{delims} is found +or end-of-file is reached. Read from @var{port} if supplied, otherwise +from the value returned by @code{(current-input-port)}. +@end deffn + +@deffn {Scheme Procedure} write-line obj [port] +@deffnx {C Function} scm_write_line (obj, port) +Display @var{obj} and a newline character to @var{port}. If +@var{port} is not specified, @code{(current-output-port)} is +used. This function is equivalent to: +@lisp +(display obj [port]) +(newline [port]) +@end lisp +@end deffn + +Some of the abovementioned I/O functions rely on the following C +primitives. These will mainly be of interest to people hacking Guile +internals. + +@deffn {Scheme Procedure} %read-delimited! delims str gobble [port [start [end]]] +@deffnx {C Function} scm_read_delimited_x (delims, str, gobble, port, start, end) +Read characters from @var{port} into @var{str} until one of the +characters in the @var{delims} string is encountered. If +@var{gobble} is true, discard the delimiter character; +otherwise, leave it in the input stream for the next read. If +@var{port} is not specified, use the value of +@code{(current-input-port)}. If @var{start} or @var{end} are +specified, store data only into the substring of @var{str} +bounded by @var{start} and @var{end} (which default to the +beginning and end of the string, respectively). + + Return a pair consisting of the delimiter that terminated the +string and the number of characters read. If reading stopped +at the end of file, the delimiter returned is the +@var{eof-object}; if the string was filled without encountering +a delimiter, this value is @code{#f}. +@end deffn + +@deffn {Scheme Procedure} %read-line [port] +@deffnx {C Function} scm_read_line (port) +Read a newline-terminated line from @var{port}, allocating storage as +necessary. The newline terminator (if any) is removed from the string, +and a pair consisting of the line and its delimiter is returned. The +delimiter may be either a newline or the @var{eof-object}; if +@code{%read-line} is called at the end of file, it returns the pair +@code{(#<eof> . #<eof>)}. +@end deffn + +@node Block Reading and Writing +@subsection Block reading and writing + +The Block-string-I/O module can be accessed with: + +@smalllisp +(use-modules (ice-9 rw)) +@end smalllisp + +It currently contains procedures that help to implement the +@code{(scsh rw)} module in guile-scsh. + +@deffn {Scheme Procedure} read-string!/partial str [port_or_fdes [start [end]]] +@deffnx {C Function} scm_read_string_x_partial (str, port_or_fdes, start, end) +Read characters from a port or file descriptor into a +string @var{str}. A port must have an underlying file +descriptor --- a so-called fport. This procedure is +scsh-compatible and can efficiently read large strings. +It will: + +@itemize +@item +attempt to fill the entire string, unless the @var{start} +and/or @var{end} arguments are supplied. i.e., @var{start} +defaults to 0 and @var{end} defaults to +@code{(string-length str)} +@item +use the current input port if @var{port_or_fdes} is not +supplied. +@item +return fewer than the requested number of characters in some +cases, e.g., on end of file, if interrupted by a signal, or if +not all the characters are immediately available. +@item +wait indefinitely for some input if no characters are +currently available, +unless the port is in non-blocking mode. +@item +read characters from the port's input buffers if available, +instead from the underlying file descriptor. +@item +return @code{#f} if end-of-file is encountered before reading +any characters, otherwise return the number of characters +read. +@item +return 0 if the port is in non-blocking mode and no characters +are immediately available. +@item +return 0 if the request is for 0 bytes, with no +end-of-file check. +@end itemize +@end deffn + +@deffn {Scheme Procedure} write-string/partial str [port_or_fdes [start [end]]] +@deffnx {C Function} scm_write_string_partial (str, port_or_fdes, start, end) +Write characters from a string @var{str} to a port or file +descriptor. A port must have an underlying file descriptor +--- a so-called fport. This procedure is +scsh-compatible and can efficiently write large strings. +It will: + +@itemize +@item +attempt to write the entire string, unless the @var{start} +and/or @var{end} arguments are supplied. i.e., @var{start} +defaults to 0 and @var{end} defaults to +@code{(string-length str)} +@item +use the current output port if @var{port_of_fdes} is not +supplied. +@item +in the case of a buffered port, store the characters in the +port's output buffer, if all will fit. If they will not fit +then any existing buffered characters will be flushed +before attempting +to write the new characters directly to the underlying file +descriptor. If the port is in non-blocking mode and +buffered characters can not be flushed immediately, then an +@code{EAGAIN} system-error exception will be raised (Note: +scsh does not support the use of non-blocking buffered ports.) +@item +write fewer than the requested number of +characters in some cases, e.g., if interrupted by a signal or +if not all of the output can be accepted immediately. +@item +wait indefinitely for at least one character +from @var{str} to be accepted by the port, unless the port is +in non-blocking mode. +@item +return the number of characters accepted by the port. +@item +return 0 if the port is in non-blocking mode and can not accept +at least one character from @var{str} immediately +@item +return 0 immediately if the request size is 0 bytes. +@end itemize +@end deffn + +@node Default Ports +@subsection Default Ports for Input, Output and Errors + +@rnindex current-input-port +@deffn {Scheme Procedure} current-input-port +@deffnx {C Function} scm_current_input_port () +Return the current input port. This is the default port used +by many input procedures. Initially, @code{current-input-port} +returns the @dfn{standard input} in Unix and C terminology. +@end deffn + +@rnindex current-output-port +@deffn {Scheme Procedure} current-output-port +@deffnx {C Function} scm_current_output_port () +Return the current output port. This is the default port used +by many output procedures. Initially, +@code{current-output-port} returns the @dfn{standard output} in +Unix and C terminology. +@end deffn + +@deffn {Scheme Procedure} current-error-port +@deffnx {C Function} scm_current_error_port () +Return the port to which errors and warnings should be sent (the +@dfn{standard error} in Unix and C terminology). +@end deffn + +@deffn {Scheme Procedure} set-current-input-port port +@deffnx {Scheme Procedure} set-current-output-port port +@deffnx {Scheme Procedure} set-current-error-port port +@deffnx {C Function} scm_set_current_input_port (port) +@deffnx {C Function} scm_set_current_output_port (port) +@deffnx {C Function} scm_set_current_error_port (port) +Change the ports returned by @code{current-input-port}, +@code{current-output-port} and @code{current-error-port}, respectively, +so that they use the supplied @var{port} for input or output. +@end deffn + +@deftypefn {C Function} void scm_frame_current_input_port (SCM port) +@deftypefnx {C Function} void scm_frame_current_output_port (SCM port) +@deftypefnx {C Function} void scm_frame_current_error_port (SCM port) +These functions must be used inside a pair of calls to +@code{scm_frame_begin} and @code{scm_frame_end} (@pxref{Frames}). +During the dynamic extent of the frame, the indicated port is set to +@var{port}. + +More precisely, the current port is swapped with a `backup' value +whenever the frame is entered or left. The backup value is +initialized with the @var{port} argument. +@end deftypefn + +@node Port Types +@subsection Types of Port + +[Types of port; how to make them.] + +@menu +* File Ports:: Ports on an operating system file. +* String Ports:: Ports on a Scheme string. +* Soft Ports:: Ports on arbitrary Scheme procedures. +* Void Ports:: Ports on nothing at all. +@end menu + + +@node File Ports +@subsubsection File Ports + +The following procedures are used to open file ports. +See also @ref{Ports and File Descriptors, open}, for an interface +to the Unix @code{open} system call. + +Most systems have limits on how many files can be open, so it's +strongly recommended that file ports be closed explicitly when no +longer required (@pxref{Ports}). + +@deffn {Scheme Procedure} open-file filename mode +@deffnx {C Function} scm_open_file (filename, mode) +Open the file whose name is @var{filename}, and return a port +representing that file. The attributes of the port are +determined by the @var{mode} string. The way in which this is +interpreted is similar to C stdio. The first character must be +one of the following: +@table @samp +@item r +Open an existing file for input. +@item w +Open a file for output, creating it if it doesn't already exist +or removing its contents if it does. +@item a +Open a file for output, creating it if it doesn't already +exist. All writes to the port will go to the end of the file. +The "append mode" can be turned off while the port is in use +@pxref{Ports and File Descriptors, fcntl} +@end table +The following additional characters can be appended: +@table @samp +@item + +Open the port for both input and output. E.g., @code{r+}: open +an existing file for both input and output. +@item 0 +Create an "unbuffered" port. In this case input and output +operations are passed directly to the underlying port +implementation without additional buffering. This is likely to +slow down I/O operations. The buffering mode can be changed +while a port is in use @pxref{Ports and File Descriptors, +setvbuf} +@item l +Add line-buffering to the port. The port output buffer will be +automatically flushed whenever a newline character is written. +@end table +In theory we could create read/write ports which were buffered +in one direction only. However this isn't included in the +current interfaces. If a file cannot be opened with the access +requested, @code{open-file} throws an exception. +@end deffn + +@rnindex open-input-file +@deffn {Scheme Procedure} open-input-file filename +Open @var{filename} for input. Equivalent to +@smalllisp +(open-file @var{filename} "r") +@end smalllisp +@end deffn + +@rnindex open-output-file +@deffn {Scheme Procedure} open-output-file filename +Open @var{filename} for output. Equivalent to +@smalllisp +(open-file @var{filename} "w") +@end smalllisp +@end deffn + +@deffn {Scheme Procedure} call-with-input-file filename proc +@deffnx {Scheme Procedure} call-with-output-file filename proc +@rnindex call-with-input-file +@rnindex call-with-output-file +Open @var{filename} for input or output, and call @code{(@var{proc} +port)} with the resulting port. Return the value returned by +@var{proc}. @var{filename} is opened as per @code{open-input-file} or +@code{open-output-file} respectively, and an error is signalled if it +cannot be opened. + +When @var{proc} returns, the port is closed. If @var{proc} does not +return (eg.@: if it throws an error), then the port might not be +closed automatically, though it will be garbage collected in the usual +way if not otherwise referenced. +@end deffn + +@deffn {Scheme Procedure} with-input-from-file filename thunk +@deffnx {Scheme Procedure} with-output-to-file filename thunk +@deffnx {Scheme Procedure} with-error-to-file filename thunk +@rnindex with-input-from-file +@rnindex with-output-to-file +Open @var{filename} and call @code{(@var{thunk})} with the new port +setup as respectively the @code{current-input-port}, +@code{current-output-port}, or @code{current-error-port}. Return the +value returned by @var{thunk}. @var{filename} is opened as per +@code{open-input-file} or @code{open-output-file} respectively, and an +error is signalled if it cannot be opened. + +When @var{thunk} returns, the port is closed and the previous setting +of the respective current port is restored. + +The current port setting is managed with @code{dynamic-wind}, so the +previous value is restored no matter how @var{thunk} exits (eg.@: an +exception), and if @var{thunk} is re-entered (via a captured +continuation) then it's set again to the @var{FILENAME} port. + +The port is closed when @var{thunk} returns normally, but not when +exited via an exception or new continuation. This ensures it's still +ready for use if @var{thunk} is re-entered by a captured continuation. +Of course the port is always garbage collected and closed in the usual +way when no longer referenced anywhere. +@end deffn + +@deffn {Scheme Procedure} port-mode port +@deffnx {C Function} scm_port_mode (port) +Return the port modes associated with the open port @var{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. +@end deffn + +@deffn {Scheme Procedure} port-filename port +@deffnx {C Function} scm_port_filename (port) +Return the filename associated with @var{port}. This function returns +the strings "standard input", "standard output" and "standard error" +when called on the current input, output and error ports respectively. +@end deffn + +@deffn {Scheme Procedure} set-port-filename! port filename +@deffnx {C Function} scm_set_port_filename_x (port, filename) +Change the filename associated with @var{port}, using the current input +port if none is specified. Note that this does not change the port's +source of data, but only the value that is returned by +@code{port-filename} and reported in diagnostic output. +@end deffn + +@deffn {Scheme Procedure} file-port? obj +@deffnx {C Function} scm_file_port_p (obj) +Determine whether @var{obj} is a port that is related to a file. +@end deffn + + +@node String Ports +@subsubsection String Ports + +The following allow string ports to be opened by analogy to R4R* +file port facilities: + +@deffn {Scheme Procedure} call-with-output-string proc +@deffnx {C Function} scm_call_with_output_string (proc) +Calls the one-argument procedure @var{proc} with a newly created output +port. When the function returns, the string composed of the characters +written into the port is returned. @var{proc} should not close the port. +@end deffn + +@deffn {Scheme Procedure} call-with-input-string string proc +@deffnx {C Function} scm_call_with_input_string (string, proc) +Calls the one-argument procedure @var{proc} with a newly +created input port from which @var{string}'s contents may be +read. The value yielded by the @var{proc} is returned. +@end deffn + +@deffn {Scheme Procedure} with-output-to-string thunk +Calls the zero-argument procedure @var{thunk} with the current output +port set temporarily to a new string port. It returns a string +composed of the characters written to the current output. +@end deffn + +@deffn {Scheme Procedure} with-input-from-string string thunk +Calls the zero-argument procedure @var{thunk} with the current input +port set temporarily to a string port opened on the specified +@var{string}. The value yielded by @var{thunk} is returned. +@end deffn + +@deffn {Scheme Procedure} open-input-string str +@deffnx {C Function} scm_open_input_string (str) +Take a string and return an input port that delivers characters +from the string. The port can be closed by +@code{close-input-port}, though its storage will be reclaimed +by the garbage collector if it becomes inaccessible. +@end deffn + +@deffn {Scheme Procedure} open-output-string +@deffnx {C Function} scm_open_output_string () +Return an output port that will accumulate characters for +retrieval by @code{get-output-string}. The port can be closed +by the procedure @code{close-output-port}, though its storage +will be reclaimed by the garbage collector if it becomes +inaccessible. +@end deffn + +@deffn {Scheme Procedure} get-output-string port +@deffnx {C Function} scm_get_output_string (port) +Given an output port created by @code{open-output-string}, +return a string consisting of the characters that have been +output to the port so far. + +@code{get-output-string} must be used before closing @var{port}, once +closed the string cannot be obtained. +@end deffn + +A string port can be used in many procedures which accept a port +but which are not dependent on implementation details of fports. +E.g., seeking and truncating will work on a string port, +but trying to extract the file descriptor number will fail. + + +@node Soft Ports +@subsubsection Soft Ports + +A @dfn{soft-port} is a port based on a vector of procedures capable of +accepting or delivering characters. It allows emulation of I/O ports. + +@deffn {Scheme Procedure} make-soft-port pv modes +@deffnx {C Function} scm_make_soft_port (pv, modes) +Return a port capable of receiving or delivering characters as +specified by the @var{modes} string (@pxref{File Ports, +open-file}). @var{pv} must be a vector of length 5 or 6. Its +components are as follows: + +@enumerate 0 +@item +procedure accepting one character for output +@item +procedure accepting a string for output +@item +thunk for flushing output +@item +thunk for getting one character +@item +thunk for closing port (not by garbage collection) +@item +(if present and not @code{#f}) thunk for computing the number of +characters that can be read from the port without blocking. +@end enumerate + +For an output-only port only elements 0, 1, 2, and 4 need be +procedures. For an input-only port only elements 3 and 4 need +be procedures. Thunks 2 and 4 can instead be @code{#f} if +there is no useful operation for them to perform. + +If thunk 3 returns @code{#f} or an @code{eof-object} +(@pxref{Input, eof-object?, ,r5rs, The Revised^5 Report on +Scheme}) it indicates that the port has reached end-of-file. +For example: + +@lisp +(define stdout (current-output-port)) +(define p (make-soft-port + (vector + (lambda (c) (write c stdout)) + (lambda (s) (display s stdout)) + (lambda () (display "." stdout)) + (lambda () (char-upcase (read-char))) + (lambda () (display "@@" stdout))) + "rw")) + +(write p p) @result{} #<input-output: soft 8081e20> +@end lisp +@end deffn + + +@node Void Ports +@subsubsection Void Ports + +This kind of port causes any data to be discarded when written to, and +always returns the end-of-file object when read from. + +@deffn {Scheme Procedure} %make-void-port mode +@deffnx {C Function} scm_sys_make_void_port (mode) +Create and return a new void port. A void port acts like +@file{/dev/null}. The @var{mode} argument +specifies the input/output modes for this port: see the +documentation for @code{open-file} in @ref{File Ports}. +@end deffn + + +@node I/O Extensions +@subsection Using and Extending Ports in C + +@menu +* C Port Interface:: Using ports from C. +* Port Implementation:: How to implement a new port type in C. +@end menu + + +@node C Port Interface +@subsubsection C Port Interface + +This section describes how to use Scheme ports from C. + +@subsubheading Port basics + +There are two main data structures. A port type object (ptob) is of +type @code{scm_ptob_descriptor}. A port instance is of type +@code{scm_port}. Given an @code{SCM} variable which points to a port, +the corresponding C port object can be obtained using the +@code{SCM_PTAB_ENTRY} macro. The ptob can be obtained by using +@code{SCM_PTOBNUM} to give an index into the @code{scm_ptobs} +global array. + +@subsubheading Port buffers + +An input port always has a read buffer and an output port always has a +write buffer. However the size of these buffers is not guaranteed to be +more than one byte (e.g., the @code{shortbuf} field in @code{scm_port} +which is used when no other buffer is allocated). The way in which the +buffers are allocated depends on the implementation of the ptob. For +example in the case of an fport, buffers may be allocated with malloc +when the port is created, but in the case of an strport the underlying +string is used as the buffer. + +@subsubheading The @code{rw_random} flag + +Special treatment is required for ports which can be seeked at random. +Before various operations, such as seeking the port or changing from +input to output on a bidirectional port or vice versa, the port +implementation must be given a chance to update its state. The write +buffer is updated by calling the @code{flush} ptob procedure and the +input buffer is updated by calling the @code{end_input} ptob procedure. +In the case of an fport, @code{flush} causes buffered output to be +written to the file descriptor, while @code{end_input} causes the +descriptor position to be adjusted to account for buffered input which +was never read. + +The special treatment must be performed if the @code{rw_random} flag in +the port is non-zero. + +@subsubheading The @code{rw_active} variable + +The @code{rw_active} variable in the port is only used if +@code{rw_random} is set. It's defined as an enum with the following +values: + +@table @code +@item SCM_PORT_READ +the read buffer may have unread data. + +@item SCM_PORT_WRITE +the write buffer may have unwritten data. + +@item SCM_PORT_NEITHER +neither the write nor the read buffer has data. +@end table + +@subsubheading Reading from a port. + +To read from a port, it's possible to either call existing libguile +procedures such as @code{scm_getc} and @code{scm_read_line} or to read +data from the read buffer directly. Reading from the buffer involves +the following steps: + +@enumerate +@item +Flush output on the port, if @code{rw_active} is @code{SCM_PORT_WRITE}. + +@item +Fill the read buffer, if it's empty, using @code{scm_fill_input}. + +@item Read the data from the buffer and update the read position in +the buffer. Steps 2) and 3) may be repeated as many times as required. + +@item Set rw_active to @code{SCM_PORT_READ} if @code{rw_random} is set. + +@item update the port's line and column counts. +@end enumerate + +@subsubheading Writing to a port. + +To write data to a port, calling @code{scm_lfwrite} should be sufficient for +most purposes. This takes care of the following steps: + +@enumerate +@item +End input on the port, if @code{rw_active} is @code{SCM_PORT_READ}. + +@item +Pass the data to the ptob implementation using the @code{write} ptob +procedure. The advantage of using the ptob @code{write} instead of +manipulating the write buffer directly is that it allows the data to be +written in one operation even if the port is using the single-byte +@code{shortbuf}. + +@item +Set @code{rw_active} to @code{SCM_PORT_WRITE} if @code{rw_random} +is set. +@end enumerate + + +@node Port Implementation +@subsubsection Port Implementation + +This section describes how to implement a new port type in C. + +As described in the previous section, a port type object (ptob) is +a structure of type @code{scm_ptob_descriptor}. A ptob is created by +calling @code{scm_make_port_type}. + +All of the elements of the ptob, apart from @code{name}, are procedures +which collectively implement the port behaviour. Creating a new port +type mostly involves writing these procedures. + +@code{scm_make_port_type} initializes three elements of the structure +(@code{name}, @code{fill_input} and @code{write}) from its arguments. +The remaining elements are initialized with default values and can be +set later if required. + +@table @code +@item name +A pointer to a NUL terminated string: the name of the port type. This +is the only element of @code{scm_ptob_descriptor} which is not +a procedure. Set via the first argument to @code{scm_make_port_type}. + +@item mark +Called during garbage collection to mark any SCM objects that a port +object may contain. It doesn't need to be set unless the port has +@code{SCM} components. Set using @code{scm_set_port_mark}. + +@item free +Called when the port is collected during gc. It +should free any resources used by the port. +Set using @code{scm_set_port_free}. + +@item print +Called when @code{write} is called on the port object, to print a +port description. e.g., for an fport it may produce something like: +@code{#<input: /etc/passwd 3>}. Set using @code{scm_set_port_print}. + +@item equalp +Not used at present. Set using @code{scm_set_port_equalp}. + +@item close +Called when the port is closed, unless it was collected during gc. It +should free any resources used by the port. +Set using @code{scm_set_port_close}. + +@item write +Accept data which is to be written using the port. The port implementation +may choose to buffer the data instead of processing it directly. +Set via the third argument to @code{scm_make_port_type}. + +@item flush +Complete the processing of buffered output data. Reset the value of +@code{rw_active} to @code{SCM_PORT_NEITHER}. +Set using @code{scm_set_port_flush}. + +@item end_input +Perform any synchronization required when switching from input to output +on the port. Reset the value of @code{rw_active} to @code{SCM_PORT_NEITHER}. +Set using @code{scm_set_port_end_input}. + +@item fill_input +Read new data into the read buffer and return the first character. It +can be assumed that the read buffer is empty when this procedure is called. +Set via the second argument to @code{scm_make_port_type}. + +@item input_waiting +Return a lower bound on the number of bytes that could be read from the +port without blocking. It can be assumed that the current state of +@code{rw_active} is @code{SCM_PORT_NEITHER}. +Set using @code{scm_set_port_input_waiting}. + +@item seek +Set the current position of the port. The procedure can not make +any assumptions about the value of @code{rw_active} when it's +called. It can reset the buffers first if desired by using something +like: + +@example + if (pt->rw_active == SCM_PORT_READ) + scm_end_input (object); + else if (pt->rw_active == SCM_PORT_WRITE) + ptob->flush (object); +@end example + +However note that this will have the side effect of discarding any data +in the unread-char buffer, in addition to any side effects from the +@code{end_input} and @code{flush} ptob procedures. This is undesirable +when seek is called to measure the current position of the port, i.e., +@code{(seek p 0 SEEK_CUR)}. The libguile fport and string port +implementations take care to avoid this problem. + +The procedure is set using @code{scm_set_port_seek}. + +@item truncate +Truncate the port data to be specified length. It can be assumed that the +current state of @code{rw_active} is @code{SCM_PORT_NEITHER}. +Set using @code{scm_set_port_truncate}. + +@end table + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/api-memory.texi b/doc/ref/api-memory.texi new file mode 100644 index 000000000..7be8d4243 --- /dev/null +++ b/doc/ref/api-memory.texi @@ -0,0 +1,478 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Memory Management +@section Memory Management and Garbage Collection + +Guile uses a @emph{garbage collector} to manage most of its objects. +While the garbage collector is designed to be mostly invisible, you +sometimes need to interact with it explicitely. + +See @ref{Garbage Collection} for a general discussion of how garbage +collection relates to using Guile from C. + +@menu +* Garbage Collection Functions:: +* Memory Blocks:: +* Weak References:: +* Guardians:: +@end menu + + +@node Garbage Collection Functions +@subsection Function related to Garbage Collection + +@deffn {Scheme Procedure} gc +@deffnx {C Function} scm_gc () +Scans all of SCM objects and reclaims for further use those that are +no longer accessible. You normally don't need to call this function +explicitly. It is called automatically when appropriate. +@end deffn + +@deftypefn {C Function} SCM scm_gc_protect_object (SCM @var{obj}) +Protects @var{obj} from being freed by the garbage collector, when it +otherwise might be. When you are done with the object, call +@code{scm_gc_unprotect_object} on the object. Calls to +@code{scm_gc_protect}/@code{scm_gc_unprotect_object} can be nested, and +the object remains protected until it has been unprotected as many times +as it was protected. It is an error to unprotect an object more times +than it has been protected. Returns the SCM object it was passed. +@end deftypefn + +@deftypefn {C Function} SCM scm_gc_unprotect_object (SCM @var{obj}) + +Unprotects an object from the garbage collector which was protected by +@code{scm_gc_unprotect_object}. Returns the SCM object it was passed. +@end deftypefn + +@deftypefn {C Function} SCM scm_permanent_object (SCM @var{obj}) + +Similar to @code{scm_gc_protect_object} in that it causes the +collector to always mark the object, except that it should not be +nested (only call @code{scm_permanent_object} on an object once), and +it has no corresponding unpermanent function. Once an object is +declared permanent, it will never be freed. Returns the SCM object it +was passed. +@end deftypefn + +@c NOTE: The varargs scm_remember_upto_here is deliberately not +@c documented, because we don't think it can be implemented as a nice +@c inline compiler directive or asm block. New _3, _4 or whatever +@c forms could certainly be added though, if needed. + +@deftypefn {C Macro} void scm_remember_upto_here_1 (SCM obj) +@deftypefnx {C Macro} void scm_remember_upto_here_2 (SCM obj1, SCM obj2) +Create a reference to the given object or objects, so they're certain +to be present on the stack or in a register and hence will not be +freed by the garbage collector before this point. + +Note that these functions can only be applied to ordinary C local +variables (ie.@: ``automatics''). Objects held in global or static +variables or some malloced block or the like cannot be protected with +this mechanism. +@end deftypefn + +@deffn {Scheme Procedure} gc-stats +@deffnx {C Function} scm_gc_stats () +Return an association list of statistics about Guile's current +use of storage. + +@deftypefun void scm_gc_mark (SCM @var{x}) +Mark the object @var{x}, and recurse on any objects @var{x} refers to. +If @var{x}'s mark bit is already set, return immediately. This function +must only be called during the mark-phase of garbage collection, +typically from a smob @emph{mark} function. +@end deftypefun + + +@end deffn + + +@node Memory Blocks +@subsection Memory Blocks + +In C programs, dynamic management of memory blocks is normally done +with the functions malloc, realloc, and free. Guile has additional +functions for dynamic memory allocation that are integrated into the +garbage collector and the error reporting system. + +Memory blocks that are associated with Scheme objects (for example a +smob) should be allocated and freed with @code{scm_gc_malloc} and +@code{scm_gc_free}. The function @code{scm_gc_malloc} will either +return a valid pointer or signal an error. It will also assume that +the new memory can be freed by a garbage collection. The garbage +collector uses this information to decide when to try to actually +collect some garbage. Memory blocks allocated with +@code{scm_gc_malloc} must be freed with @code{scm_gc_free}. + +For memory that is not associated with a Scheme object, you can use +@code{scm_malloc} instead of @code{malloc}. Like +@code{scm_gc_malloc}, it will either return a valid pointer or signal +an error. However, it will not assume that the new memory block can +be freed by a garbage collection. The memory can be freed with +@code{free}. + +There is also @code{scm_gc_realloc} and @code{scm_realloc}, to be used +in place of @code{realloc} when appropriate, @code{scm_gc_calloc} and +@code{scm_calloc}, to be used in place of @code{calloc} when +appropriate. + +For really specialized needs, take at look at +@code{scm_gc_register_collectable_memory} and +@code{scm_gc_unregister_collectable_memory}. + +@deftypefn {C Function} {void *} scm_malloc (size_t @var{size}) +@deftypefnx {C Function} {void *} scm_calloc (size_t @var{size}) +Allocate @var{size} bytes of memory and return a pointer to it. When +@var{size} is 0, return @code{NULL}. When not enough memory is +available, signal an error. This function runs the GC to free up some +memory when it deems it appropriate. + +The memory is allocated by the libc @code{malloc} function and can be +freed with @code{free}. There is no @code{scm_free} function to go +with @code{scm_malloc} to make it easier to pass memory back and forth +between different modules. + +The function @code{scm_calloc} is similar to @code{scm_malloc}, but +initializes the block of memory to zero as well. +@end deftypefn + +@deftypefn {C Function} {void *} scm_realloc (void *@var{mem}, size_t @var{new_size}) +Change the size of the memory block at @var{mem} to @var{new_size} and +return its new location. When @var{new_size} is 0, this is the same +as calling @code{free} on @var{mem} and @code{NULL} is returned. When +@var{mem} is @code{NULL}, this function behaves like @code{scm_malloc} +and allocates a new block of size @var{new_size}. + +When not enough memory is available, signal an error. This function +runs the GC to free up some memory when it deems it appropriate. +@end deftypefn + + + + +@deftypefn {C Function} void scm_gc_register_collectable_memory (void *@var{mem}, size_t @var{size}, const char *@var{what}) +Informs the GC that the memory at @var{mem} of size @var{size} can +potentially be freed during a GC. That is, announce that @var{mem} is +part of a GC controlled object and when the GC happens to free that +object, @var{size} bytes will be freed along with it. The GC will +@strong{not} free the memory itself, it will just know that so-and-so +much bytes of memory are associated with GC controlled objects and the +memory system figures this into its decisions when to run a GC. + +@var{mem} does not need to come from @code{scm_malloc}. You can only +call this function once for every memory block. + +The @var{what} argument is used for statistical purposes. It should +describe the type of object that the memory will be used for so that +users can identify just what strange objects are eating up their +memory. +@end deftypefn + +@deftypefn {C Function} void scm_gc_unregister_collectable_memory (void *@var{mem}, size_t @var{size}) +Informs the GC that the memory at @var{mem} of size @var{size} is no +longer associated with a GC controlled object. You must take care to +match up every call to @code{scm_gc_register_collectable_memory} with +a call to @code{scm_gc_unregister_collectable_memory}. If you don't do +this, the GC might have a wrong impression of what is going on and run +much less efficiently than it could. +@end deftypefn + +@deftypefn {C Function} {void *} scm_gc_malloc (size_t @var{size}, const char *@var{what}) +@deftypefnx {C Function} {void *} scm_gc_realloc (void *@var{mem}, size_t @var{old_size}, size_t @var{new_size}, const char *@var{what}); +@deftypefnx {C Function} {void *} scm_gc_calloc (size_t @var{size}, const char *@var{what}) +Like @code{scm_malloc}, @code{scm_realloc} or @code{scm_calloc}, but +also call @code{scm_gc_register_collectable_memory}. Note that you +need to pass the old size of a reallocated memory block as well. See +below for a motivation. +@end deftypefn + + +@deftypefn {C Function} void scm_gc_free (void *@var{mem}, size_t @var{size}, const char *@var{what}) +Like @code{free}, but also call @code{scm_gc_unregister_collectable_memory}. + +Note that you need to explicitely pass the @var{size} parameter. This +is done since it should normally be easy to provide this parameter +(for memory that is associated with GC controlled objects) and this +frees us from tracking this value in the GC itself, which will keep +the memory management overhead very low. +@end deftypefn + +@deffn {Scheme Procedure} malloc-stats +Return an alist ((@var{what} . @var{n}) ...) describing number +of malloced objects. +@var{what} is the second argument to @code{scm_gc_malloc}, +@var{n} is the number of objects of that type currently +allocated. +@end deffn + + +@subsubsection Upgrading from scm_must_malloc et al. + +Version 1.6 of Guile and earlier did not have the functions from the +previous section. In their place, it had the functions +@code{scm_must_malloc}, @code{scm_must_realloc} and +@code{scm_must_free}. This section explains why we want you to stop +using them, and how to do this. + +@findex scm_must_malloc +@findex scm_must_realloc +@findex scm_must_calloc +@findex scm_must_free +The functions @code{scm_must_malloc} and @code{scm_must_realloc} +behaved like @code{scm_gc_malloc} and @code{scm_gc_realloc} do now, +respectively. They would inform the GC about the newly allocated +memory via the internal equivalent of +@code{scm_gc_register_collectable_memory}. However, +@code{scm_must_free} did not unregister the memory it was about to +free. The usual way to unregister memory was to return its size from +a smob free function. + +This disconnectedness of the actual freeing of memory and reporting +this to the GC proved to be bad in practice. It was easy to make +mistakes and report the wrong size because allocating and freeing was +not done with symmetric code, and because it is cumbersome to compute +the total size of nested data structures that were freed with multiple +calls to @code{scm_must_free}. Additionally, there was no equivalent +to @code{scm_malloc}, and it was tempting to just use +@code{scm_must_malloc} and never to tell the GC that the memory has +been freed. + +The effect was that the internal statistics kept by the GC drifted out +of sync with reality and could even overflow in long running programs. +When this happened, the result was a dramatic increase in (senseless) +GC activity which would effectively stop the program dead. + +@findex scm_done_malloc +@findex scm_done_free +The functions @code{scm_done_malloc} and @code{scm_done_free} were +introduced to help restore balance to the force, but existing bugs did +not magically disappear, of course. + +Therefore we decided to force everybody to review their code by +deprecating the existing functions and introducing new ones in their +place that are hopefully easier to use correctly. + +For every use of @code{scm_must_malloc} you need to decide whether to +use @code{scm_malloc} or @code{scm_gc_malloc} in its place. When the +memory block is not part of a smob or some other Scheme object whose +lifetime is ultimately managed by the garbage collector, use +@code{scm_malloc} and @code{free}. When it is part of a smob, use +@code{scm_gc_malloc} and change the smob free function to use +@code{scm_gc_free} instead of @code{scm_must_free} or @code{free} and +make it return zero. + +The important thing is to always pair @code{scm_malloc} with +@code{free}; and to always pair @code{scm_gc_malloc} with +@code{scm_gc_free}. + +The same reasoning applies to @code{scm_must_realloc} and +@code{scm_realloc} versus @code{scm_gc_realloc}. + + +@node Weak References +@subsection Weak References + +[FIXME: This chapter is based on Mikael Djurfeldt's answer to a +question by Michael Livshin. Any mistakes are not theirs, of course. ] + +Weak references let you attach bookkeeping information to data so that +the additional information automatically disappears when the original +data is no longer in use and gets garbage collected. In a weak key hash, +the hash entry for that key disappears as soon as the key is no longer +referenced from anywhere else. For weak value hashes, the same happens +as soon as the value is no longer in use. Entries in a doubly weak hash +disappear when either the key or the value are not used anywhere else +anymore. + +Object properties offer the same kind of functionality as weak key +hashes in many situations. (@pxref{Object Properties}) + +Here's an example (a little bit strained perhaps, but one of the +examples is actually used in Guile): + +Assume that you're implementing a debugging system where you want to +associate information about filename and position of source code +expressions with the expressions themselves. + +Hashtables can be used for that, but if you use ordinary hash tables +it will be impossible for the scheme interpreter to "forget" old +source when, for example, a file is reloaded. + +To implement the mapping from source code expressions to positional +information it is necessary to use weak-key tables since we don't want +the expressions to be remembered just because they are in our table. + +To implement a mapping from source file line numbers to source code +expressions you would use a weak-value table. + +To implement a mapping from source code expressions to the procedures +they constitute a doubly-weak table has to be used. + +@menu +* Weak key hashes:: +* Weak vectors:: +@end menu + + +@node Weak key hashes +@subsubsection Weak key hashes + +@deffn {Scheme Procedure} make-weak-key-hash-table size +@deffnx {Scheme Procedure} make-weak-value-hash-table size +@deffnx {Scheme Procedure} make-doubly-weak-hash-table size +@deffnx {C Function} scm_make_weak_key_hash_table (size) +@deffnx {C Function} scm_make_weak_value_hash_table (size) +@deffnx {C Function} scm_make_doubly_weak_hash_table (size) +Return a weak hash table with @var{size} buckets. As with any +hash table, choosing a good size for the table requires some +caution. + +You can modify weak hash tables in exactly the same way you +would modify regular hash tables. (@pxref{Hash Tables}) +@end deffn + +@deffn {Scheme Procedure} weak-key-hash-table? obj +@deffnx {Scheme Procedure} weak-value-hash-table? obj +@deffnx {Scheme Procedure} doubly-weak-hash-table? obj +@deffnx {C Function} scm_weak_key_hash_table_p (obj) +@deffnx {C Function} scm_weak_value_hash_table_p (obj) +@deffnx {C Function} scm_doubly_weak_hash_table_p (obj) +Return @code{#t} if @var{obj} is the specified weak hash +table. Note that a doubly weak hash table is neither a weak key +nor a weak value hash table. +@end deffn + +@deffn {Scheme Procedure} make-weak-value-hash-table k +@end deffn + +@deffn {Scheme Procedure} weak-value-hash-table? x +@end deffn + +@deffn {Scheme Procedure} make-doubly-weak-hash-table k +@end deffn + +@deffn {Scheme Procedure} doubly-weak-hash-table? x +@end deffn + + +@node Weak vectors +@subsubsection Weak vectors + +Weak vectors are mainly useful in Guile's implementation of weak hash +tables. + +@deffn {Scheme Procedure} make-weak-vector size [fill] +@deffnx {C Function} scm_make_weak_vector (size, fill) +Return a weak vector with @var{size} elements. If the optional +argument @var{fill} is given, all entries in the vector will be +set to @var{fill}. The default value for @var{fill} is the +empty list. +@end deffn + +@deffn {Scheme Procedure} weak-vector . l +@deffnx {Scheme Procedure} list->weak-vector l +@deffnx {C Function} scm_weak_vector (l) +Construct a weak vector from a list: @code{weak-vector} uses +the list of its arguments while @code{list->weak-vector} uses +its only argument @var{l} (a list) to construct a weak vector +the same way @code{list->vector} would. +@end deffn + +@deffn {Scheme Procedure} weak-vector? obj +@deffnx {C Function} scm_weak_vector_p (obj) +Return @code{#t} if @var{obj} is a weak vector. Note that all +weak hashes are also weak vectors. +@end deffn + + +@node Guardians +@subsection Guardians + +@deffn {Scheme Procedure} make-guardian [greedy?] +@deffnx {C Function} scm_make_guardian (greedy_p) +Create a new guardian. +A guardian protects a set of objects from garbage collection, +allowing a program to apply cleanup or other actions. + +@code{make-guardian} returns a procedure representing the guardian. +Calling the guardian procedure with an argument adds the +argument to the guardian's set of protected objects. +Calling the guardian procedure without an argument returns +one of the protected objects which are ready for garbage +collection, or @code{#f} if no such object is available. +Objects which are returned in this way are removed from +the guardian. + +@code{make-guardian} takes one optional argument that says whether the +new guardian should be greedy or sharing. If there is any chance +that any object protected by the guardian may be resurrected, +then you should make the guardian greedy (this is the default). + +See R. Kent Dybvig, Carl Bruggeman, and David Eby (1993) +"Guardians in a Generation-Based Garbage Collector". +ACM SIGPLAN Conference on Programming Language Design +and Implementation, June 1993. + +(the semantics are slightly different at this point, but the +paper still (mostly) accurately describes the interface). +@end deffn + +@deffn {Scheme Procedure} destroy-guardian! guardian +@deffnx {C Function} scm_destroy_guardian_x (guardian) +Destroys @var{guardian}, by making it impossible to put any more +objects in it or get any objects from it. It also unguards any +objects guarded by @var{guardian}. +@end deffn + +@deffn {Scheme Procedure} guardian-greedy? guardian +@deffnx {C Function} scm_guardian_greedy_p (guardian) +Return @code{#t} if @var{guardian} is a greedy guardian, otherwise @code{#f}. +@end deffn + +@deffn {Scheme Procedure} guardian-destroyed? guardian +@deffnx {C Function} scm_guardian_destroyed_p (guardian) +Return @code{#t} if @var{guardian} has been destroyed, otherwise @code{#f}. +@end deffn + + +@page +@node Objects +@section Objects + +@deffn {Scheme Procedure} entity? obj +@deffnx {C Function} scm_entity_p (obj) +Return @code{#t} if @var{obj} is an entity. +@end deffn + +@deffn {Scheme Procedure} operator? obj +@deffnx {C Function} scm_operator_p (obj) +Return @code{#t} if @var{obj} is an operator. +@end deffn + +@deffn {Scheme Procedure} set-object-procedure! obj proc +@deffnx {C Function} scm_set_object_procedure_x (obj, proc) +Set the object procedure of @var{obj} to @var{proc}. +@var{obj} must be either an entity or an operator. +@end deffn + +@deffn {Scheme Procedure} make-class-object metaclass layout +@deffnx {C Function} scm_make_class_object (metaclass, layout) +Create a new class object of class @var{metaclass}, with the +slot layout specified by @var{layout}. +@end deffn + +@deffn {Scheme Procedure} make-subclass-object class layout +@deffnx {C Function} scm_make_subclass_object (class, layout) +Create a subclass object of @var{class}, with the slot layout +specified by @var{layout}. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/api-modules.texi b/doc/ref/api-modules.texi new file mode 100644 index 000000000..822c396fe --- /dev/null +++ b/doc/ref/api-modules.texi @@ -0,0 +1,1042 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Modules +@section Modules +@cindex modules + +When programs become large, naming conflicts can occur when a function +or global variable defined in one file has the same name as a function +or global variable in another file. Even just a @emph{similarity} +between function names can cause hard-to-find bugs, since a programmer +might type the wrong function name. + +The approach used to tackle this problem is called @emph{information +encapsulation}, which consists of packaging functional units into a +given name space that is clearly separated from other name spaces. +@cindex encapsulation +@cindex information encapsulation +@cindex name space + +The language features that allow this are usually called @emph{the +module system} because programs are broken up into modules that are +compiled separately (or loaded separately in an interpreter). + +Older languages, like C, have limited support for name space +manipulation and protection. In C a variable or function is public by +default, and can be made local to a module with the @code{static} +keyword. But you cannot reference public variables and functions from +another module with different names. + +More advanced module systems have become a common feature in recently +designed languages: ML, Python, Perl, and Modula 3 all allow the +@emph{renaming} of objects from a foreign module, so they will not +clutter the global name space. +@cindex name space - private + +In addition, Guile offers variables as first-class objects. They can +be used for interacting with the module system. + +@menu +* provide and require:: The SLIB feature mechanism. +* Environments:: R5RS top-level environments. +* The Guile module system:: How Guile does it. +* Dynamic Libraries:: Loading libraries of compiled code at run time. +* Variables:: First-class variables. +@end menu + +@node provide and require +@subsection provide and require + +Aubrey Jaffer, mostly to support his portable Scheme library SLIB, +implemented a provide/require mechanism for many Scheme implementations. +Library files in SLIB @emph{provide} a feature, and when user programs +@emph{require} that feature, the library file is loaded in. + +For example, the file @file{random.scm} in the SLIB package contains the +line + +@smalllisp +(provide 'random) +@end smalllisp + +so to use its procedures, a user would type + +@smalllisp +(require 'random) +@end smalllisp + +and they would magically become available, @emph{but still have the same +names!} So this method is nice, but not as good as a full-featured +module system. + +When SLIB is used with Guile, provide and require can be used to access +its facilities. + +@node Environments +@subsection Environments +@cindex environment + +Scheme, as defined in R5RS, does @emph{not} have a full module system. +However it does define the concept of a top-level @dfn{environment}. +Such an environment maps identifiers (symbols) to Scheme objects such +as procedures and lists: @ref{About Closure}. In other words, it +implements a set of @dfn{bindings}. + +Environments in R5RS can be passed as the second argument to +@code{eval} (@pxref{Fly Evaluation}). Three procedures are defined to +return environments: @code{scheme-report-environment}, +@code{null-environment} and @code{interaction-environment} (@pxref{Fly +Evaluation}). + +In addition, in Guile any module can be used as an R5RS environment, +i.e., passed as the second argument to @code{eval}. + +Note: the following two procedures are available only when the +@code{(ice-9 r5rs)} module is loaded: + +@smalllisp +(use-modules (ice-9 r5rs)) +@end smalllisp + +@deffn {Scheme Procedure} scheme-report-environment version +@deffnx {Scheme Procedure} null-environment version +@var{version} must be the exact integer `5', corresponding to revision +5 of the Scheme report (the Revised^5 Report on Scheme). +@code{scheme-report-environment} returns a specifier for an +environment that is empty except for all bindings defined in the +report that are either required or both optional and supported by the +implementation. @code{null-environment} returns a specifier for an +environment that is empty except for the (syntactic) bindings for all +syntactic keywords defined in the report that are either required or +both optional and supported by the implementation. + +Currently Guile does not support values of @var{version} for other +revisions of the report. + +The effect of assigning (through the use of @code{eval}) a variable +bound in a @code{scheme-report-environment} (for example @code{car}) +is unspecified. Currently the environments specified by +@code{scheme-report-environment} are not immutable in Guile. +@end deffn + +@node The Guile module system +@subsection The Guile module system + +The Guile module system extends the concept of environments, discussed +in the previous section, with mechanisms to define, use and customise +sets of bindings. + +In 1996 Tom Lord implemented a full-featured module system for Guile which +allows loading Scheme source files into a private name space. This system has +been in available since at least Guile version 1.1. + +For Guile version 1.5.0 and later, the system has been improved to have better +integration from C code, more fine-grained user control over interfaces, and +documentation. + +Although it is anticipated that the module system implementation will +change in the future, the Scheme programming interface described in this +manual should be considered stable. The C programming interface is +considered relatively stable, although at the time of this writing, +there is still some flux. + +@menu +* General Information about Modules:: Guile module basics. +* Using Guile Modules:: How to use existing modules. +* Creating Guile Modules:: How to package your code into modules. +* Module System Quirks:: Strange things to be aware of. +* Included Guile Modules:: Which modules come with Guile? +* Accessing Modules from C:: How to work with modules with C code. +@end menu + +@node General Information about Modules +@subsubsection General Information about Modules + +A Guile module can be thought of as a collection of named procedures, +variables and macros. More precisely, it is a set of @dfn{bindings} +of symbols (names) to Scheme objects. + +An environment is a mapping from identifiers (or symbols) to locations, +i.e., a set of bindings. +There are top-level environments and lexical environments. +The environment in which a lambda is executed is remembered as part of its +definition. + +Within a module, all bindings are visible. Certain bindings +can be declared @dfn{public}, in which case they are added to the +module's so-called @dfn{export list}; this set of public bindings is +called the module's @dfn{public interface} (@pxref{Creating Guile +Modules}). + +A client module @dfn{uses} a providing module's bindings by either +accessing the providing module's public interface, or by building a +custom interface (and then accessing that). In a custom interface, the +client module can @dfn{select} which bindings to access and can also +algorithmically @dfn{rename} bindings. In contrast, when using the +providing module's public interface, the entire export list is available +without renaming (@pxref{Using Guile Modules}). + +To use a module, it must be found and loaded. All Guile modules have a +unique @dfn{module name}, which is a list of one or more symbols. +Examples are @code{(ice-9 popen)} or @code{(srfi srfi-11)}. When Guile +searches for the code of a module, it constructs the name of the file to +load by concatenating the name elements with slashes between the +elements and appending a number of file name extensions from the list +@code{%load-extensions} (@pxref{Loading}). The resulting file name is +then searched in all directories in the variable @code{%load-path} +(@pxref{Build Config}). For example, the @code{(ice-9 popen)} module +would result in the filename @code{ice-9/popen.scm} and searched in the +installation directories of Guile and in all other directories in the +load path. + +@c FIXME::martin: Not sure about this, maybe someone knows better? +Every module has a so-called syntax transformer associated with it. +This is a procedure which performs all syntax transformation for the +time the module is read in and evaluated. When working with modules, +you can manipulate the current syntax transformer using the +@code{use-syntax} syntactic form or the @code{#:use-syntax} module +definition option (@pxref{Creating Guile Modules}). + +Please note that there are some problems with the current module system +you should keep in mind (@pxref{Module System Quirks}). We hope to +address these eventually. + + +@node Using Guile Modules +@subsubsection Using Guile Modules + +To use a Guile module is to access either its public interface or a +custom interface (@pxref{General Information about Modules}). Both +types of access are handled by the syntactic form @code{use-modules}, +which accepts one or more interface specifications and, upon evaluation, +arranges for those interfaces to be available to the current module. +This process may include locating and loading code for a given module if +that code has not yet been loaded, following %load-path (@pxref{Build +Config}). + +An @dfn{interface specification} has one of two forms. The first +variation is simply to name the module, in which case its public +interface is the one accessed. For example: + +@smalllisp +(use-modules (ice-9 popen)) +@end smalllisp + +Here, the interface specification is @code{(ice-9 popen)}, and the +result is that the current module now has access to @code{open-pipe}, +@code{close-pipe}, @code{open-input-pipe}, and so on (@pxref{Included +Guile Modules}). + +Note in the previous example that if the current module had already +defined @code{open-pipe}, that definition would be overwritten by the +definition in @code{(ice-9 popen)}. For this reason (and others), there +is a second variation of interface specification that not only names a +module to be accessed, but also selects bindings from it and renames +them to suit the current module's needs. For example: + +@smalllisp +(use-modules ((ice-9 popen) + :select ((open-pipe . pipe-open) close-pipe) + :renamer (symbol-prefix-proc 'unixy:))) +@end smalllisp + +Here, the interface specification is more complex than before, and the +result is that a custom interface with only two bindings is created and +subsequently accessed by the current module. The mapping of old to new +names is as follows: + +@c Use `smallexample' since `table' is ugly. --ttn +@smallexample +(ice-9 popen) sees: current module sees: +open-pipe unixy:pipe-open +close-pipe unixy:close-pipe +@end smallexample + +This example also shows how to use the convenience procedure +@code{symbol-prefix-proc}. + +You can also directly refer to bindings in a module by using the +@code{@@} syntax. For example, instead of using the +@code{use-modules} statement from above and writing +@code{unixy:pipe-open} to refer to the @code{pipe-open} from the +@code{(ice-9 popen)}, you could also write @code{(@@ (ice-9 popen) +open-pipe)}. Thus an alternative to the complete @code{use-modules} +statement would be + +@smalllisp +(define unixy:pipe-open (@@ (ice-9 popen) open-pipe)) +(define unixy:close-pipe (@@ (ice-9 popen) close-pipe)) +@end smalllisp + +There is also @code{@@@@}, which can be used like @code{@@}, but does +not check whether the variable that is being accessed is actually +exported. Thus, @code{@@@@} can be thought of as the impolite version +of @code{@@} and should only be used as a last resort or for +debugging, for example. + +Note that just as with a @code{use-modules} statement, any module that +has not yet been loaded yet will be loaded when referenced by a +@code{@@} or @code{@@@@} form. + +You can also use the @code{@@} and @code{@@@@} syntaxes as the target +of a @code{set!} when the binding refers to a variable. + +@c begin (scm-doc-string "boot-9.scm" "symbol-prefix-proc") +@deffn {Scheme Procedure} symbol-prefix-proc prefix-sym +Return a procedure that prefixes its arg (a symbol) with +@var{prefix-sym}. +@c Insert gratuitous C++ slam here. --ttn +@end deffn + +@c begin (scm-doc-string "boot-9.scm" "use-modules") +@deffn syntax use-modules spec @dots{} +Resolve each interface specification @var{spec} into an interface and +arrange for these to be accessible by the current module. The return +value is unspecified. + +@var{spec} can be a list of symbols, in which case it names a module +whose public interface is found and used. + +@var{spec} can also be of the form: + +@smalllisp + (MODULE-NAME [:select SELECTION] [:renamer RENAMER]) +@end smalllisp + +in which case a custom interface is newly created and used. +@var{module-name} is a list of symbols, as above; @var{selection} is a +list of selection-specs; and @var{renamer} is a procedure that takes a +symbol and returns its new name. A selection-spec is either a symbol or +a pair of symbols @code{(ORIG . SEEN)}, where @var{orig} is the name in +the used module and @var{seen} is the name in the using module. Note +that @var{seen} is also passed through @var{renamer}. + +The @code{:select} and @code{:renamer} clauses are optional. If both are +omitted, the returned interface has no bindings. If the @code{:select} +clause is omitted, @var{renamer} operates on the used module's public +interface. + +Signal error if module name is not resolvable. +@end deffn + + +@c FIXME::martin: Is this correct, and is there more to say? +@c FIXME::martin: Define term and concept `system transformer' somewhere. + +@deffn syntax use-syntax module-name +Load the module @code{module-name} and use its system +transformer as the system transformer for the currently defined module, +as well as installing it as the current system transformer. +@end deffn + +@deffn syntax @@ module-name binding-name +Refer to the binding named @var{binding-name} in module +@var{module-name}. The binding must have been exported by the module. +@end deffn + +@deffn syntax @@@@ module-name binding-name +Refer to the binding named @var{binding-name} in module +@var{module-name}. The binding must not have been exported by the +module. This syntax is only intended for debugging purposes or as a +last resort. +@end deffn + +@node Creating Guile Modules +@subsubsection Creating Guile Modules + +When you want to create your own modules, you have to take the following +steps: + +@itemize @bullet +@item +Create a Scheme source file and add all variables and procedures you wish +to export, or which are required by the exported procedures. + +@item +Add a @code{define-module} form at the beginning. + +@item +Export all bindings which should be in the public interface, either +by using @code{define-public} or @code{export} (both documented below). +@end itemize + +@c begin (scm-doc-string "boot-9.scm" "define-module") +@deffn syntax define-module module-name [options @dots{}] +@var{module-name} is of the form @code{(hierarchy file)}. One +example of this is + +@smalllisp +(define-module (ice-9 popen)) +@end smalllisp + +@code{define-module} makes this module available to Guile programs under +the given @var{module-name}. + +The @var{options} are keyword/value pairs which specify more about the +defined module. The recognized options and their meaning is shown in +the following table. + +@c fixme: Should we use "#:" or ":"? + +@table @code +@item #:use-module @var{interface-specification} +Equivalent to a @code{(use-modules @var{interface-specification})} +(@pxref{Using Guile Modules}). + +@item #:use-syntax @var{module} +Use @var{module} when loading the currently defined module, and install +it as the syntax transformer. + +@item #:autoload @var{module} @var{symbol} +Load @var{module} whenever @var{symbol} is accessed. + +@item #:export @var{list} +Export all identifiers in @var{list}, which must be a list of symbols. +This is equivalent to @code{(export @var{list})} in the module body. + +@item #:no-backtrace +Tell Guile not to record information for procedure backtraces when +executing the procedures in this module. + +@item #:pure +Create a @dfn{pure} module, that is a module which does not contain any +of the standard procedure bindings except for the syntax forms. This is +useful if you want to create @dfn{safe} modules, that is modules which +do not know anything about dangerous procedures. +@end table + +@end deffn +@c end + +@deffn syntax export variable @dots{} +Add all @var{variable}s (which must be symbols) to the list of exported +bindings of the current module. +@end deffn + +@c begin (scm-doc-string "boot-9.scm" "define-public") +@deffn syntax define-public @dots{} +Equivalent to @code{(begin (define foo ...) (export foo))}. +@end deffn +@c end + + +@node Module System Quirks +@subsubsection Module System Quirks + +Although the programming interfaces are relatively stable, the Guile +module system itself is still evolving. Here are some situations where +usage surpasses design. + +@itemize @bullet + +@item +When using a module which exports a macro definition, the other module +must export all bindings the macro expansion uses, too, because the +expanded code would otherwise not be able to see these definitions and +issue a ``variable unbound'' error, or worse, would use another binding +which might be present in the scope of the expansion. + +@item +When two or more used modules export bindings with the same names, the +last accessed module wins, and the exported binding of that last module +will silently be used. This might lead to hard-to-find errors because +wrong procedures or variables are used. To avoid this kind of +@dfn{name-clash} situation, use a custom interface specification +(@pxref{Using Guile Modules}). (We include this entry for the possible +benefit of users of Guile versions previous to 1.5.0, when custom +interfaces were added to the module system.) + +@item +[Add other quirks here.] + +@end itemize + + +@node Included Guile Modules +@subsubsection Included Guile Modules + +@c FIXME::martin: Review me! + +Some modules are included in the Guile distribution; here are references +to the entries in this manual which describe them in more detail: + +@table @strong +@item boot-9 +boot-9 is Guile's initialization module, and it is always loaded when +Guile starts up. + +@item (ice-9 debug) +Mikael Djurfeldt's source-level debugging support for Guile +(@pxref{Debugging Features}). + +@item (ice-9 threads) +Guile's support for multi threaded execution (@pxref{Scheduling}). + +@item (ice-9 rdelim) +Line- and character-delimited input (@pxref{Line/Delimited}). + +@item (ice-9 rw) +Block string input/output (@pxref{Block Reading and Writing}). + +@item (ice-9 documentation) +Online documentation (REFFIXME). + +@item (srfi srfi-1) +A library providing a lot of useful list and pair processing +procedures (@pxref{SRFI-1}). + +@item (srfi srfi-2) +Support for @code{and-let*} (@pxref{SRFI-2}). + +@item (srfi srfi-4) +Support for homogeneous numeric vectors (@pxref{SRFI-4}). + +@item (srfi srfi-6) +Support for some additional string port procedures (@pxref{SRFI-6}). + +@item (srfi srfi-8) +Multiple-value handling with @code{receive} (@pxref{SRFI-8}). + +@item (srfi srfi-9) +Record definition with @code{define-record-type} (@pxref{SRFI-9}). + +@item (srfi srfi-10) +Read hash extension @code{#,()} (@pxref{SRFI-10}). + +@item (srfi srfi-11) +Multiple-value handling with @code{let-values} and @code{let-values*} +(@pxref{SRFI-11}). + +@item (srfi srfi-13) +String library (@pxref{SRFI-13}). + +@item (srfi srfi-14) +Character-set library (@pxref{SRFI-14}). + +@item (srfi srfi-17) +Getter-with-setter support (@pxref{SRFI-17}). + +@item (srfi srfi-26) +Convenient syntax for partial application (@pxref{SRFI-26}) + +@item (ice-9 slib) +This module contains hooks for using Aubrey Jaffer's portable Scheme +library SLIB from Guile (@pxref{SLIB}). + +@c FIXME::martin: This module is not in the distribution. Remove it +@c from here? +@item (ice-9 jacal) +This module contains hooks for using Aubrey Jaffer's symbolic math +package Jacal from Guile (@pxref{JACAL}). +@end table + + +@node Accessing Modules from C +@subsubsection Accessing Modules from C + +The last sections have described how modules are used in Scheme code, +which is the recommended way of creating and accessing modules. You +can also work with modules from C, but it is more cumbersome. + +The following procedures are available. + +@deftypefn {C Procedure} SCM scm_current_module () +Return the module that is the @emph{current module}. +@end deftypefn + +@deftypefn {C Procedure} SCM scm_set_current_module (SCM @var{module}) +Set the current module to @var{module} and return the previous current +module. +@end deftypefn + +@deftypefn {C Procedure} SCM scm_c_call_with_current_module (SCM @var{module}, SCM (*@var{func})(void *), void *@var{data}) +Call @var{func} and make @var{module} the current module during the +call. The argument @var{data} is passed to @var{func}. The return +value of @code{scm_c_call_with_current_module} is the return value of +@var{func}. +@end deftypefn + +@deftypefn {C Procedure} SCM scm_c_lookup (const char *@var{name}) +Return the variable bound to the symbol indicated by @var{name} in the +current module. If there is no such binding or the symbol is not +bound to a variable, signal an error. +@end deftypefn + +@deftypefn {C Procedure} SCM scm_lookup (SCM @var{name}) +Like @code{scm_c_lookup}, but the symbol is specified directly. +@end deftypefn + +@deftypefn {C Procedure} SCM scm_c_module_lookup (SCM @var{module}, const char *@var{name}) +@deftypefnx {C Procedure} SCM scm_module_lookup (SCM @var{module}, SCM @var{name}) +Like @code{scm_c_lookup} and @code{scm_lookup}, but the specified +module is used instead of the current one. +@end deftypefn + +@deftypefn {C Procedure} SCM scm_c_define (const char *@var{name}, SCM @var{val}) +Bind the symbol indicated by @var{name} to a variable in the current +module and set that variable to @var{val}. When @var{name} is already +bound to a variable, use that. Else create a new variable. +@end deftypefn + +@deftypefn {C Procedure} SCM scm_define (SCM @var{name}, SCM @var{val}) +Like @code{scm_c_define}, but the symbol is specified directly. +@end deftypefn + +@deftypefn {C Procedure} SCM scm_c_module_define (SCM @var{module}, const char *@var{name}, SCM @var{val}) +@deftypefnx {C Procedure} SCM scm_module_define (SCM @var{module}, SCM @var{name}, SCM @var{val}) +Like @code{scm_c_define} and @code{scm_define}, but the specified +module is used instead of the current one. +@end deftypefn + +@deftypefn {C Procedure} SCM scm_module_reverse_lookup (SCM @var{module}, SCM @var{variable}) +Find the symbol that is bound to @var{variable} in @var{module}. When no such binding is found, return @var{#f}. +@end deftypefn + +@deftypefn {C Procedure} SCM scm_c_define_module (const char *@var{name}, void (*@var{init})(void *), void *@var{data}) +Define a new module named @var{name} and make it current while +@var{init} is called, passing it @var{data}. Return the module. + +The parameter @var{name} is a string with the symbols that make up +the module name, separated by spaces. For example, @samp{"foo bar"} names +the module @samp{(foo bar)}. + +When there already exists a module named @var{name}, it is used +unchanged, otherwise, an empty module is created. +@end deftypefn + +@deftypefn {C Procedure} SCM scm_c_resolve_module (const char *@var{name}) +Find the module name @var{name} and return it. When it has not +already been defined, try to auto-load it. When it can't be found +that way either, create an empty module. The name is interpreted as +for @code{scm_c_define_module}. +@end deftypefn + +@deftypefn {C Procedure} SCM scm_resolve_module (SCM @var{name}) +Like @code{scm_c_resolve_module}, but the name is given as a real list +of symbols. +@end deftypefn + +@deftypefn {C Procedure} SCM scm_c_use_module (const char *@var{name}) +Add the module named @var{name} to the uses list of the current +module, as with @code{(use-modules @var{name})}. The name is +interpreted as for @code{scm_c_define_module}. +@end deftypefn + +@deftypefn {C Procedure} SCM scm_c_export (const char *@var{name}, ...) +Add the bindings designated by @var{name}, ... to the public interface +of the current module. The list of names is terminated by +@code{NULL}. +@end deftypefn + +@node Dynamic Libraries +@subsection Dynamic Libraries + +Most modern Unices have something called @dfn{shared libraries}. This +ordinarily means that they have the capability to share the executable +image of a library between several running programs to save memory and +disk space. But generally, shared libraries give a lot of additional +flexibility compared to the traditional static libraries. In fact, +calling them `dynamic' libraries is as correct as calling them `shared'. + +Shared libraries really give you a lot of flexibility in addition to the +memory and disk space savings. When you link a program against a shared +library, that library is not closely incorporated into the final +executable. Instead, the executable of your program only contains +enough information to find the needed shared libraries when the program +is actually run. Only then, when the program is starting, is the final +step of the linking process performed. This means that you need not +recompile all programs when you install a new, only slightly modified +version of a shared library. The programs will pick up the changes +automatically the next time they are run. + +Now, when all the necessary machinery is there to perform part of the +linking at run-time, why not take the next step and allow the programmer +to explicitly take advantage of it from within his program? Of course, +many operating systems that support shared libraries do just that, and +chances are that Guile will allow you to access this feature from within +your Scheme programs. As you might have guessed already, this feature +is called @dfn{dynamic linking}.@footnote{Some people also refer to the +final linking stage at program startup as `dynamic linking', so if you +want to make yourself perfectly clear, it is probably best to use the +more technical term @dfn{dlopening}, as suggested by Gordon Matzigkeit +in his libtool documentation.} + +As with many aspects of Guile, there is a low-level way to access the +dynamic linking apparatus, and a more high-level interface that +integrates dynamically linked libraries into the module system. + +@menu +* Low level dynamic linking:: +* Compiled Code Modules:: +* Dynamic Linking and Compiled Code Modules:: +@end menu + +@node Low level dynamic linking +@subsubsection Low level dynamic linking + +When using the low level procedures to do your dynamic linking, you have +complete control over which library is loaded when and what gets done +with it. + +@deffn {Scheme Procedure} dynamic-link library +@deffnx {C Function} scm_dynamic_link (library) +Find the shared library denoted by @var{library} (a string) and link it +into the running Guile application. When everything works out, return a +Scheme object suitable for representing the linked object file. +Otherwise an error is thrown. How object files are searched is system +dependent. + +Normally, @var{library} is just the name of some shared library file +that will be searched for in the places where shared libraries usually +reside, such as in @file{/usr/lib} and @file{/usr/local/lib}. +@end deffn + +@deffn {Scheme Procedure} dynamic-object? obj +@deffnx {C Function} scm_dynamic_object_p (obj) +Return @code{#t} if @var{obj} is a dynamic library handle, or @code{#f} +otherwise. +@end deffn + +@deffn {Scheme Procedure} dynamic-unlink dobj +@deffnx {C Function} scm_dynamic_unlink (dobj) +Unlink the indicated object file from the application. The +argument @var{dobj} must have been obtained by a call to +@code{dynamic-link}. After @code{dynamic-unlink} has been +called on @var{dobj}, its content is no longer accessible. +@end deffn + +@deffn {Scheme Procedure} dynamic-func name dobj +@deffnx {C Function} scm_dynamic_func (name, dobj) +Search the dynamic object @var{dobj} for the C function +indicated by the string @var{name} and return some Scheme +handle that can later be used with @code{dynamic-call} to +actually call the function. + +Regardless whether your C compiler prepends an underscore @samp{_} to +the global names in a program, you should @strong{not} include this +underscore in @var{function}. Guile knows whether the underscore is +needed or not and will add it when necessary. +@end deffn + +@deffn {Scheme Procedure} dynamic-call func dobj +@deffnx {C Function} scm_dynamic_call (func, dobj) +Call the C function indicated by @var{func} and @var{dobj}. +The function is passed no arguments and its return value is +ignored. When @var{function} is something returned by +@code{dynamic-func}, call that function and ignore @var{dobj}. +When @var{func} is a string , look it up in @var{dynobj}; this +is equivalent to +@smallexample +(dynamic-call (dynamic-func @var{func} @var{dobj}) #f) +@end smallexample + +Interrupts are deferred while the C function is executing (with +@code{SCM_DEFER_INTS}/@code{SCM_ALLOW_INTS}). +@end deffn + +@deffn {Scheme Procedure} dynamic-args-call func dobj args +@deffnx {C Function} scm_dynamic_args_call (func, dobj, args) +Call the C function indicated by @var{func} and @var{dobj}, +just like @code{dynamic-call}, but pass it some arguments and +return its return value. The C function is expected to take +two arguments and return an @code{int}, just like @code{main}: +@smallexample +int c_func (int argc, char **argv); +@end smallexample + +The parameter @var{args} must be a list of strings and is +converted into an array of @code{char *}. The array is passed +in @var{argv} and its size in @var{argc}. The return value is +converted to a Scheme number and returned from the call to +@code{dynamic-args-call}. +@end deffn + +When dynamic linking is disabled or not supported on your system, +the above functions throw errors, but they are still available. + +Here is a small example that works on GNU/Linux: + +@smallexample +(define libc-obj (dynamic-link "libc.so")) +libc-obj +@result{} #<dynamic-object "libc.so"> +(dynamic-args-call 'rand libc-obj '()) +@result{} 269167349 +(dynamic-unlink libc-obj) +libc-obj +@result{} #<dynamic-object "libc.so" (unlinked)> +@end smallexample + +As you can see, after calling @code{dynamic-unlink} on a dynamically +linked library, it is marked as @samp{(unlinked)} and you are no longer +able to use it with @code{dynamic-call}, etc. Whether the library is +really removed from you program is system-dependent and will generally +not happen when some other parts of your program still use it. In the +example above, @code{libc} is almost certainly not removed from your +program because it is badly needed by almost everything. + +The functions to call a function from a dynamically linked library, +@code{dynamic-call} and @code{dynamic-args-call}, are not very powerful. +They are mostly intended to be used for calling specially written +initialization functions that will then add new primitives to Guile. +For example, we do not expect that you will dynamically link +@file{libX11} with @code{dynamic-link} and then construct a beautiful +graphical user interface just by using @code{dynamic-call} and +@code{dynamic-args-call}. Instead, the usual way would be to write a +special Guile<->X11 glue library that has intimate knowledge about both +Guile and X11 and does whatever is necessary to make them inter-operate +smoothly. This glue library could then be dynamically linked into a +vanilla Guile interpreter and activated by calling its initialization +function. That function would add all the new types and primitives to +the Guile interpreter that it has to offer. + +From this setup the next logical step is to integrate these glue +libraries into the module system of Guile so that you can load new +primitives into a running system just as you can load new Scheme code. + +There is, however, another possibility to get a more thorough access to +the functions contained in a dynamically linked library. Anthony Green +has written @file{libffi}, a library that implements a @dfn{foreign +function interface} for a number of different platforms. With it, you +can extend the Spartan functionality of @code{dynamic-call} and +@code{dynamic-args-call} considerably. There is glue code available in +the Guile contrib archive to make @file{libffi} accessible from Guile. + +@node Compiled Code Modules +@subsubsection Putting Compiled Code into Modules + +The new primitives that you add to Guile with +@code{scm_c_define_gsubr} (@pxref{Primitive Procedures}) or with any +of the other mechanisms are placed into the @code{(guile-user)} module +by default. However, it is also possible to put new primitives into +other modules. + +The mechanism for doing so is not very well thought out and is likely to +change when the module system of Guile itself is revised, but it is +simple and useful enough to document it as it stands. + +What @code{scm_c_define_gsubr} and the functions used by the snarfer +really do is to add the new primitives to whatever module is the +@emph{current module} when they are called. This is analogous to the +way Scheme code is put into modules: the @code{define-module} expression +at the top of a Scheme source file creates a new module and makes it the +current module while the rest of the file is evaluated. The +@code{define} expressions in that file then add their new definitions to +this current module. + +Therefore, all we need to do is to make sure that the right module is +current when calling @code{scm_c_define_gsubr} for our new primitives. + +@node Dynamic Linking and Compiled Code Modules +@subsubsection Dynamic Linking and Compiled Code Modules + +The most interesting application of dynamically linked libraries is +probably to use them for providing @emph{compiled code modules} to +Scheme programs. As much fun as programming in Scheme is, every now and +then comes the need to write some low-level C stuff to make Scheme even +more fun. + +Not only can you put these new primitives into their own module (see the +previous section), you can even put them into a shared library that is +only then linked to your running Guile image when it is actually +needed. + +An example will hopefully make everything clear. Suppose we want to +make the Bessel functions of the C library available to Scheme in the +module @samp{(math bessel)}. First we need to write the appropriate +glue code to convert the arguments and return values of the functions +from Scheme to C and back. Additionally, we need a function that will +add them to the set of Guile primitives. Because this is just an +example, we will only implement this for the @code{j0} function. + +@c FIXME::martin: Change all gh_ references to their scm_ equivalents. + +@smallexample +#include <math.h> +#include <libguile.h> + +SCM +j0_wrapper (SCM x) +@{ + return scm_double2num (j0 (scm_num2dbl (x, "j0"))); +@} + +void +init_math_bessel () +@{ + scm_c_define_gsubr ("j0", 1, 0, 0, j0_wrapper); +@} +@end smallexample + +We can already try to bring this into action by manually calling the low +level functions for performing dynamic linking. The C source file needs +to be compiled into a shared library. Here is how to do it on +GNU/Linux, please refer to the @code{libtool} documentation for how to +create dynamically linkable libraries portably. + +@smallexample +gcc -shared -o libbessel.so -fPIC bessel.c +@end smallexample + +Now fire up Guile: + +@smalllisp +(define bessel-lib (dynamic-link "./libbessel.so")) +(dynamic-call "init_math_bessel" bessel-lib) +(j0 2) +@result{} 0.223890779141236 +@end smalllisp + +The filename @file{./libbessel.so} should be pointing to the shared +library produced with the @code{gcc} command above, of course. The +second line of the Guile interaction will call the +@code{init_math_bessel} function which in turn will register the C +function @code{j0_wrapper} with the Guile interpreter under the name +@code{j0}. This function becomes immediately available and we can call +it from Scheme. + +Fun, isn't it? But we are only half way there. This is what +@code{apropos} has to say about @code{j0}: + +@smallexample +(apropos "j0") +@print{} (guile-user): j0 #<primitive-procedure j0> +@end smallexample + +As you can see, @code{j0} is contained in the root module, where all +the other Guile primitives like @code{display}, etc live. In general, +a primitive is put into whatever module is the @dfn{current module} at +the time @code{scm_c_define_gsubr} is called. + +A compiled module should have a specially named @dfn{module init +function}. Guile knows about this special name and will call that +function automatically after having linked in the shared library. For +our example, we replace @code{init_math_bessel} with the following code in +@file{bessel.c}: + +@smallexample +void +init_math_bessel (void *unused) +@{ + scm_c_define_gsubr ("j0", 1, 0, 0, j0_wrapper); + scm_c_export ("j0", NULL); +@} + +void +scm_init_math_bessel_module () +@{ + scm_c_define_module ("math bessel", init_math_bessel, NULL); +@} +@end smallexample + +The general pattern for the name of a module init function is: +@samp{scm_init_}, followed by the name of the module where the +individual hierarchical components are concatenated with underscores, +followed by @samp{_module}. + +After @file{libbessel.so} has been rebuilt, we need to place the shared +library into the right place. + +Once the module has been correctly installed, it should be possible to +use it like this: + +@smallexample +guile> (load-extension "./libbessel.so" "scm_init_math_bessel_module") +guile> (use-modules (math bessel)) +guile> (j0 2) +0.223890779141236 +guile> (apropos "j0") +@print{} (math bessel): j0 #<primitive-procedure j0> +@end smallexample + +That's it! + +@node Variables +@subsection Variables +@tpindex Variables + +Each module has its own hash table, sometimes known as an @dfn{obarray}, +that maps the names defined in that module to their corresponding +variable objects. + +A variable is a box-like object that can hold any Scheme value. It is +said to be @dfn{undefined} if its box holds a special Scheme value that +denotes undefined-ness (which is different from all other Scheme values, +including for example @code{#f}); otherwise the variable is +@dfn{defined}. + +On its own, a variable object is anonymous. A variable is said to be +@dfn{bound} when it is associated with a name in some way, usually a +symbol in a module obarray. When this happens, the relationship is +mutual: the variable is bound to the name (in that module), and the name +(in that module) is bound to the variable. + +(That's the theory, anyway. In practice, defined-ness and bound-ness +sometimes get confused, because Lisp and Scheme implementations have +often conflated --- or deliberately drawn no distinction between --- a +name that is unbound and a name that is bound to a variable whose value +is undefined. We will try to be clear about the difference and explain +any confusion where it is unavoidable.) + +Variables do not have a read syntax. Most commonly they are created and +bound implicitly by @code{define} expressions: a top-level @code{define} +expression of the form + +@lisp +(define @var{name} @var{value}) +@end lisp + +@noindent +creates a variable with initial value @var{value} and binds it to the +name @var{name} in the current module. But they can also be created +dynamically by calling one of the constructor procedures +@code{make-variable} and @code{make-undefined-variable}. + +First-class variables are especially useful for interacting with the +current module system (@pxref{The Guile module system}). + +@deffn {Scheme Procedure} make-undefined-variable +@deffnx {C Function} scm_make_undefined_variable () +Return a variable that is initially unbound. +@end deffn + +@deffn {Scheme Procedure} make-variable init +@deffnx {C Function} scm_make_variable (init) +Return a variable initialized to value @var{init}. +@end deffn + +@deffn {Scheme Procedure} variable-bound? var +@deffnx {C Function} scm_variable_bound_p (var) +Return @code{#t} iff @var{var} is bound to a value. +Throws an error if @var{var} is not a variable object. +@end deffn + +@deffn {Scheme Procedure} variable-ref var +@deffnx {C Function} scm_variable_ref (var) +Dereference @var{var} and return its value. +@var{var} must be a variable object; see @code{make-variable} +and @code{make-undefined-variable}. +@end deffn + +@deffn {Scheme Procedure} variable-set! var val +@deffnx {C Function} scm_variable_set_x (var, val) +Set the value of the variable @var{var} to @var{val}. +@var{var} must be a variable object, @var{val} can be any +value. Return an unspecified value. +@end deffn + +@deffn {Scheme Procedure} variable? obj +@deffnx {C Function} scm_variable_p (obj) +Return @code{#t} iff @var{obj} is a variable object, else +return @code{#f}. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/api-options.texi b/doc/ref/api-options.texi new file mode 100644 index 000000000..144c665a6 --- /dev/null +++ b/doc/ref/api-options.texi @@ -0,0 +1,731 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Options and Config +@section Configuration, Features and Runtime Options + +Why is my Guile different from your Guile? There are three kinds of +possible variation: + +@itemize @bullet +@item +build differences --- different versions of the Guile source code, +installation directories, configuration flags that control pieces of +functionality being included or left out, etc. + +@item +differences in dynamically loaded code --- behaviour and features +provided by modules that can be dynamically loaded into a running Guile + +@item +different runtime options --- some of the options that are provided for +controlling Guile's behaviour may be set differently. +@end itemize + +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. +@end menu + + +@node Build Config +@subsection Configuration, Build and Installation + +The following procedures and variables provide information about how +Guile was configured, built and installed on your system. + +@deffn {Scheme Procedure} version +@deffnx {Scheme Procedure} effective-version +@deffnx {Scheme Procedure} major-version +@deffnx {Scheme Procedure} minor-version +@deffnx {Scheme Procedure} micro-version +@deffnx {C Function} scm_version () +@deffnx {C Function} scm_effective_version () +@deffnx {C Function} scm_major_version () +@deffnx {C Function} scm_minor_version () +@deffnx {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 @code{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. @file{/usr/share/guile/1.6/} + +@lisp +(version) @result{} "1.6.0" +(effective-version) @result{} "1.6" +(major-version) @result{} "1" +(minor-version) @result{} "6" +(micro-version) @result{} "0" +@end lisp +@end deffn + +@deffn {Scheme Procedure} %package-data-dir +@deffnx {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 +@file{/usr/local/share/guile} or @file{/usr/share/guile}. +@end deffn + +@deffn {Scheme Procedure} %library-dir +@deffnx {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 +@file{/usr/local/share/guile/<GUILE_EFFECTIVE_VERSION>} or +@file{/usr/share/guile/<GUILE_EFFECTIVE_VERSION>}, for example: +@file{/usr/local/share/guile/1.6}. +@end deffn + +@deffn {Scheme Procedure} %site-dir +@deffnx {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 +@file{/usr/local/share/guile/site} or @file{/usr/share/guile/site}. +@end deffn + +@cindex GUILE_LOAD_PATH +@defvar %load-path +List of directories which should be searched for Scheme modules and +libraries. @code{%load-path} is initialized when Guile starts up to +@code{(list (%site-dir) (%library-dir) (%package-data-dir) ".")}, +prepended with the contents of the GUILE_LOAD_PATH environment variable, +if it is set. +@end defvar + +@deffn {Scheme Procedure} parse-path path [tail] +@deffnx {C Function} scm_parse_path (path, tail) +Parse @var{path}, which is expected to be a colon-separated +string, into a list and return the resulting list with +@var{tail} appended. If @var{path} is @code{#f}, @var{tail} +is returned. +@end deffn + +@deffn {Scheme Procedure} search-path path filename [extensions] +@deffnx {C Function} scm_search_path (path, filename, extensions) +Search @var{path} for a directory containing a file named +@var{filename}. The file must be readable, and not a directory. +If we find one, return its full filename; otherwise, return +@code{#f}. If @var{filename} is absolute, return it unchanged. +If given, @var{extensions} is a list of strings; for each +directory in @var{path}, we search for @var{filename} +concatenated with each @var{extension}. +@end deffn + +@defvar %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 @code{%guile-build-info}, by group: + +@cindex @code{srcdir} +@cindex @code{top_srcdir} +@cindex @code{prefix} +@cindex @code{exec_prefix} +@cindex @code{bindir} +@cindex @code{sbindir} +@cindex @code{libexecdir} +@cindex @code{datadir} +@cindex @code{sysconfdir} +@cindex @code{sharedstatedir} +@cindex @code{localstatedir} +@cindex @code{libdir} +@cindex @code{infodir} +@cindex @code{mandir} +@cindex @code{includedir} +@cindex @code{pkgdatadir} +@cindex @code{pkglibdir} +@cindex @code{pkgincludedir} +@table @asis +@item directories +srcdir, top_srcdir, prefix, exec_prefix, bindir, sbindir, libexecdir, +datadir, sysconfdir, sharedstatedir, localstatedir, libdir, infodir, +mandir, includedir, pkgdatadir, pkglibdir, pkgincludedir +@cindex @code{LIBS} +@item env vars +LIBS +@cindex @code{guileversion} +@cindex @code{libguileinterface} +@cindex @code{buildstamp} +@item versioning info +guileversion, libguileinterface, buildstamp +@end table + +Values are all strings. The value for @code{LIBS} is typically found +also as a part of "guile-config link" output. The value for +@code{guileversion} has form X.Y.Z, and should be the same as returned +by @code{(version)}. The value for @code{libguileinterface} is libtool +compatible and has form CURRENT:REVISION:AGE. The value for +@code{buildstamp} is the output of the date(1) command. + +In the source, @code{%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. +@end defvar + + +@node Feature Tracking +@subsection Feature Tracking + +Guile has a Scheme level variable @code{*features*} that keeps track to +some extent of the features that are available in a running Guile. +@code{*features*} is a list of symbols, for example @code{threads}, each +of which describes a feature of the running Guile process. + +@defvar *features* +A list of symbols describing available features of the Guile process. +@end defvar + +You shouldn't modify the @code{*features*} variable directly using +@code{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. +@end menu + + +@node Feature Manipulation +@subsubsection Feature Manipulation + +To check whether a particular feature is available, use the +@code{provided?} procedure: + +@deffn {Scheme Procedure} provided? feature +@deffnx {Deprecated Scheme Procedure} feature? feature +Return @code{#t} if the specified @var{feature} is available, otherwise +@code{#f}. +@end deffn + +To advertise a feature from your own Scheme code, you can use the +@code{provide} procedure: + +@deffn {Scheme Procedure} provide feature +Add @var{feature} to the list of available features in this Guile +process. +@end deffn + +For C code, the equivalent function takes its feature name as a +@code{char *} argument for convenience: + +@deftypefn {C Function} void scm_add_feature (const char *str) +Add a symbol with name @var{str} to the list of available features in +this Guile process. +@end deftypefn + + +@node Common Feature Symbols +@subsubsection 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. + +@table @code +@item array +Indicates support for arrays (@pxref{Arrays}). + +@item array-for-each +Indicates availability of @code{array-for-each} and other array mapping +procedures (@pxref{Array Mapping}). + +@item char-ready? +Indicates that the @code{char-ready?} function is available +(@pxref{Reading}). + +@item complex +Indicates support for complex numbers. + +@item current-time +Indicates availability of time-related functions: @code{times}, +@code{get-internal-run-time} and so on (@pxref{Time}). + +@item debug-extensions +Indicates that the debugging evaluator is available, together with the +options for controlling it. + +@item delay +Indicates support for promises (@pxref{Delayed Evaluation}). + +@item EIDs +Indicates that the @code{geteuid} and @code{getegid} really return +effective user and group IDs (@pxref{Processes}). + +@item inexact +Indicates support for inexact numbers. + +@item i/o-extensions +Indicates availability of the following extended I/O procedures: +@code{ftell}, @code{redirect-port}, @code{dup->fdes}, @code{dup2}, +@code{fileno}, @code{isatty?}, @code{fdopen}, +@code{primitive-move->fdes} and @code{fdes->ports} (@pxref{Ports and +File Descriptors}). + +@item net-db +Indicates availability of network database functions: +@code{scm_gethost}, @code{scm_getnet}, @code{scm_getproto}, +@code{scm_getserv}, @code{scm_sethost}, @code{scm_setnet}, @code{scm_setproto}, +@code{scm_setserv}, and their `byXXX' variants (@pxref{Network +Databases}). + +@item posix +Indicates support for POSIX functions: @code{pipe}, @code{getgroups}, +@code{kill}, @code{execl} and so on (@pxref{POSIX}). + +@item random +Indicates availability of random number generation functions: +@code{random}, @code{copy-random-state}, @code{random-uniform} and so on +(@pxref{Random}). + +@item reckless +Indicates that Guile was built with important checks omitted --- you +should never see this! + +@item regex +Indicates support for POSIX regular expressions using +@code{make-regexp}, @code{regexp-exec} and friends (@pxref{Regexp +Functions}). + +@item socket +Indicates availability of socket-related functions: @code{socket}, +@code{bind}, @code{connect} and so on (@pxref{Network Sockets and +Communication}). + +@item sort +Indicates availability of sorting and merging functions +(@pxref{Sorting}). + +@item system +Indicates that the @code{system} function is available +(@pxref{Processes}). + +@item threads +Indicates support for multithreading (@pxref{Threads}). + +@item values +Indicates support for multiple return values using @code{values} and +@code{call-with-values} (@pxref{Multiple Values}). +@end table + +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. + +@table @code +@item defmacro +Indicates that the @code{defmacro} macro is available (@pxref{Macros}). + +@item describe +Indicates that the @code{(oop goops describe)} module has been loaded, +which provides a procedure for describing the contents of GOOPS +instances. + +@item readline +Indicates that Guile has loaded in Readline support, for command line +editing (@pxref{Readline Support}). + +@item record +Indicates support for record definition using @code{make-record-type} +and friends (@pxref{Records}). +@end table + +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 @code{defined?} procedure +than to test for the corresponding feature using @code{provided?}. + + +@node Runtime Options +@subsection 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 @emph{reading}, @emph{printing}, @emph{debugging} or +@emph{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:: +@end menu + + +@node Low level options interfaces +@subsubsection Low Level Options Interfaces + +@deffn {Scheme Procedure} read-options-interface [setting] +@deffnx {Scheme Procedure} eval-options-interface [setting] +@deffnx {Scheme Procedure} print-options-interface [setting] +@deffnx {Scheme Procedure} debug-options-interface [setting] +@deffnx {Scheme Procedure} evaluator-traps-interface [setting] +@deffnx {C Function} scm_read_options (setting) +@deffnx {C Function} scm_eval_options_interface (setting) +@deffnx {C Function} scm_print_options (setting) +@deffnx {C Function} scm_debug_options (setting) +@deffnx {C Function} scm_evaluator_traps (setting) +If one of these procedures is called with no arguments (or with +@code{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 @code{'help}, these +procedures return a list of entries like @code{(@var{OPTION-SYMBOL} +@var{DEFAULT-VALUE} @var{DOC-STRING})}, with each entry giving the +default value and documentation for each option symbol in the relevant +set of options. +@end deffn + + +@node User level options interfaces +@subsubsection User Level Options Interfaces + +@c @deftp {Data type} scm_option +@c @code{scm_option} is used to represent run time options. It can be a +@c @emph{boolean} type, in which case the option will be set by the strings +@c @code{"yes"} and @code{"no"}. It can be a +@c @end deftp + +@c NJFIXME +@deffn {Scheme Procedure} <group>-options [arg] +@deffnx {Scheme Procedure} read-options [arg] +@deffnx {Scheme Procedure} print-options [arg] +@deffnx {Scheme Procedure} debug-options [arg] +@deffnx {Scheme Procedure} traps [arg] +These functions list the options in their group. The optional argument +@var{arg} is a symbol which modifies the form in which the options are +presented. + +With no arguments, @code{<group>-options} returns the values of the +options in that particular group. If @var{arg} is @code{'help}, a +description of each option is given. If @var{arg} is @code{'full}, +programmers' options are also shown. + +@var{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. +@end deffn +[FIXME: I don't think 'full is ever any different from 'help. What's +up?] + +@c NJFIXME +@deffn {Scheme Procedure} <group>-enable option-symbol +@deffnx {Scheme Procedure} read-enable option-symbol +@deffnx {Scheme Procedure} print-enable option-symbol +@deffnx {Scheme Procedure} debug-enable option-symbol +@deffnx {Scheme Procedure} trap-enable option-symbol +These functions set the specified @var{option-symbol} in their options +group. They only work if the option is boolean, and throw an error +otherwise. +@end deffn + +@c NJFIXME +@deffn {Scheme Procedure} <group>-disable option-symbol +@deffnx {Scheme Procedure} read-disable option-symbol +@deffnx {Scheme Procedure} print-disable option-symbol +@deffnx {Scheme Procedure} debug-disable option-symbol +@deffnx {Scheme Procedure} trap-disable option-symbol +These functions turn off the specified @var{option-symbol} in their +options group. They only work if the option is boolean, and throw an +error otherwise. +@end deffn + +@c NJFIXME +@deffn syntax <group>-set! option-symbol value +@deffnx syntax read-set! option-symbol value +@deffnx syntax print-set! option-symbol value +@deffnx syntax debug-set! option-symbol value +@deffnx syntax trap-set! option-symbol value +These functions set a non-boolean @var{option-symbol} to the specified +@var{value}. +@end deffn + + +@node Reader options +@subsubsection Reader options +@cindex options - read +@cindex read options + +Here is the list of reader options generated by typing +@code{(read-options 'full)} in Guile. You can also see the default +values. + +@smalllisp +keywords #f Style of keyword recognition: #f or 'prefix +case-insensitive no Convert symbols to lower case. +positions yes Record positions of source code expressions. +copy no Copy source code expressions. +@end smalllisp + +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 + +@smalllisp +(read-enable 'case-insensitive) +@end smalllisp + +@node Printing options +@subsubsection Printing options + +Here is the list of print options generated by typing +@code{(print-options 'full)} in Guile. You can also see the default +values. + +@smallexample +source no Print closures with source. +closure-hook #f Hook for printing closures. +@end smallexample + + +@node Evaluator options +@subsubsection Evaluator options + +These are the evaluator options with their default values, as they are +printed by typing @code{(eval-options 'full)} in Guile. + +@smallexample +stack 22000 Size of thread stacks (in machine words). +@end smallexample + + +@node Evaluator trap options +@subsubsection 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 +@code{(traps 'full)} in Guile. You can also see the default values. + +@smallexample +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. +@end smallexample + +@deffn apply-frame-handler key cont tailp +Called when a procedure is being applied. + +Called if: + +@itemize @bullet +@item +evaluator traps are enabled [traps interface], and +@item +either +@itemize @minus +@item +@code{apply-frame} is enabled [traps interface], or +@item +trace mode is on [debug-options interface], and the procedure being +called has the trace property enabled. +@end itemize +@end itemize + +If cheap traps are enabled [debug-options interface], @var{cont} is a +debug object, otherwise it is a restartable continuation. + +@var{tailp} is true if this is a tail call +@end deffn + +@deffn exit-frame-handler key cont retval +Called when a value is returned from a procedure. + +Called if: + +@itemize @bullet +@item +evaluator traps are enabled [traps interface], and +@item +either +@itemize @minus +@item + @code{exit-frame} is enabled [traps interface], or +@item +trace mode is on [debug-options interface], and the procedure being +called has the trace property enabled. +@end itemize +@end itemize + +If cheap traps are enabled [debug-options interface], @var{cont} is a +debug object, otherwise it is a restartable continuation. + +@var{retval} is the return value. +@end deffn + +@node Debugger options +@subsubsection Debugger options + +Here is the list of print options generated by typing +@code{(debug-options 'full)} in Guile. You can also see the default +values. + +@smallexample +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 *Flyweight representation of the stack at traps. +@end smallexample + +@subsubheading Stack overflow + +@cindex overflow, stack +@cindex stack overflow +Stack overflow errors are caused by a computation trying to use more +stack space than has been enabled by the @code{stack} option. They are +reported like this: + +@lisp +(non-tail-recursive-factorial 500) +@print{} +ERROR: Stack overflow +ABORT: (stack-overflow) +@end lisp + +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 @code{debug-set!}, for example: + +@lisp +(debug-set! stack 200000) +@result{} +(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) +@result{} +122013682599111006870123878542304692625357434@dots{} +@end lisp + +If you prefer to try rewriting your code, you may be able to save stack +space by making some of your procedures @dfn{tail recursive}. For a +description of what this means, see @ref{Proper tail +recursion,,,r5rs,The Revised^5 Report on Scheme}. + + +@node Examples of option use +@subsubsection 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 + +@enumerate +@item +Notices that the symbols @code{abc} and @code{aBc} are not the same +@item +Examines the @code{read-options}, and sees that @code{case-insensitive} +is set to ``no''. +@item +Enables @code{case-insensitive} +@item +Verifies that now @code{aBc} and @code{abc} are the same +@item +Disables @code{case-insensitive} and enables debugging @code{backtrace} +@item +Reproduces the error of displaying @code{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.] +@end enumerate + + +@smalllisp +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 or 'prefix +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 *Flyweight representation of the stack at traps. +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> +@end smalllisp + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/api-overview.texi b/doc/ref/api-overview.texi new file mode 100644 index 000000000..48378895e --- /dev/null +++ b/doc/ref/api-overview.texi @@ -0,0 +1,112 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node API Overview +@section Overview of the Guile API + +Guile's application programming interface (@dfn{API}) makes +functionality available that an application developer can use in either +C or Scheme programming. The interface consists of @dfn{elements} that +may be macros, functions or variables in C, and procedures, variables, +syntax or other types of object in Scheme. + +Many elements are available to both Scheme and C, in a form that is +appropriate. For example, the @code{assq} Scheme procedure is also +available as @code{scm_assq} to C code. These elements are documented +only once, addressing both the Scheme and C aspects of them. + +The Scheme name of an element is related to its C name in a regular +way. Also, a C function takes its parameters in a systematic way. + +Normally, the name of a C function can be derived given its Scheme name, +using some simple textual transformations: + +@itemize @bullet + +@item +Replace @code{-} (hyphen) with @code{_} (underscore). + +@item +Replace @code{?} (question mark) with @code{_p}. + +@item +Replace @code{!} (exclamation point) with @code{_x}. + +@item +Replace internal @code{->} with @code{_to_}. + +@item +Replace @code{<=} (less than or equal) with @code{_leq}. + +@item +Replace @code{>=} (greater than or equal) with @code{_geq}. + +@item +Replace @code{<} (less than) with @code{_less}. + +@item +Replace @code{>} (greater than) with @code{_gr}. + +@item +Prefix with @code{scm_}. + +@end itemize + +@c Here is an Emacs Lisp command that prompts for a Scheme function name and +@c inserts the corresponding C function name into the buffer. + +@c @example +@c (defun insert-scheme-to-C (name &optional use-gh) +@c "Transforms Scheme NAME, a string, to its C counterpart, and inserts it. +@c Prefix arg non-nil means use \"gh_\" prefix, otherwise use \"scm_\" prefix." +@c (interactive "sScheme name: \nP") +@c (let ((transforms '(("-" . "_") +@c ("?" . "_p") +@c ("!" . "_x") +@c ("->" . "_to_") +@c ("<=" . "_leq") +@c (">=" . "_geq") +@c ("<" . "_less") +@c (">" . "_gr") +@c ("@@" . "at")))) +@c (while transforms +@c (let ((trigger (concat "\\(.*\\)" +@c (regexp-quote (caar transforms)) +@c "\\(.*\\)")) +@c (sub (cdar transforms)) +@c (m nil)) +@c (while (setq m (string-match trigger name)) +@c (setq name (concat (match-string 1 name) +@c sub +@c (match-string 2 name))))) +@c (setq transforms (cdr transforms)))) +@c (insert (if use-gh "gh_" "scm_") name)) +@c @end example + +A C function always takes a fixed number of arguments of type +@code{SCM}, even when the corresponding Scheme function takes a +variable number. + +For some Scheme functions, some last arguments are optional; the +corresponding C function must always be invoked with all optional +arguments specified. To get the effect as if an argument has not been +specified, pass @code{SCM_UNDEFINED} as its value. You can not do +this for an argument in the middle; when one argument is +@code{SCM_UNDEFINED} all the ones following it must be +@code{SCM_UNDEFINED} as well. + +Some Scheme functions take an arbitrary number of @emph{rest} +arguments; the corresponding C function must be invoked with a list of +all these arguments. This list is always the last argument of the C +function. + +These two variants can also be combined. + +The type of the return value of a C function that corresponds to a +Scheme function is always @code{SCM}. In the descriptions below, +types are therefore often omitted bot for the return value and for the +arguments. diff --git a/doc/ref/api-procedures.texi b/doc/ref/api-procedures.texi new file mode 100644 index 000000000..08ae7c2c5 --- /dev/null +++ b/doc/ref/api-procedures.texi @@ -0,0 +1,859 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Procedures and Macros +@section Procedures and Macros + +@menu +* Lambda:: Basic procedure creation using lambda. +* Primitive Procedures:: Procedures defined in C. +* Optional Arguments:: Handling keyword, optional and rest arguments. +* Procedure Properties:: Procedure properties and meta-information. +* Procedures with Setters:: Procedures with setters. +* Macros:: Lisp style macro definitions. +* Syntax Rules:: Support for R5RS @code{syntax-rules}. +* Syntax Case:: Support for the @code{syntax-case} system. +* Internal Macros:: Guile's internal representation. +@end menu + + +@node Lambda +@subsection Lambda: Basic Procedure Creation +@cindex lambda + +@c FIXME::martin: Review me! + +A @code{lambda} expression evaluates to a procedure. The environment +which is in effect when a @code{lambda} expression is evaluated is +enclosed in the newly created procedure, this is referred to as a +@dfn{closure} (@pxref{About Closure}). + +When a procedure created by @code{lambda} is called with some actual +arguments, the environment enclosed in the procedure is extended by +binding the variables named in the formal argument list to new locations +and storing the actual arguments into these locations. Then the body of +the @code{lambda} expression is evaluation sequentially. The result of +the last expression in the procedure body is then the result of the +procedure invocation. + +The following examples will show how procedures can be created using +@code{lambda}, and what you can do with these procedures. + +@lisp +(lambda (x) (+ x x)) @result{} @r{a procedure} +((lambda (x) (+ x x)) 4) @result{} 8 +@end lisp + +The fact that the environment in effect when creating a procedure is +enclosed in the procedure is shown with this example: + +@lisp +(define add4 + (let ((x 4)) + (lambda (y) (+ x y)))) +(add4 6) @result{} 10 +@end lisp + + +@deffn syntax lambda formals body +@var{formals} should be a formal argument list as described in the +following table. + +@table @code +@item (@var{variable1} @dots{}) +The procedure takes a fixed number of arguments; when the procedure is +called, the arguments will be stored into the newly created location for +the formal variables. +@item @var{variable} +The procedure takes any number of arguments; when the procedure is +called, the sequence of actual arguments will converted into a list and +stored into the newly created location for the formal variable. +@item (@var{variable1} @dots{} @var{variablen} . @var{variablen+1}) +If a space-delimited period precedes the last variable, then the +procedure takes @var{n} or more variables where @var{n} is the number +of formal arguments before the period. There must be at least one +argument before the period. The first @var{n} actual arguments will be +stored into the newly allocated locations for the first @var{n} formal +arguments and the sequence of the remaining actual arguments is +converted into a list and the stored into the location for the last +formal argument. If there are exactly @var{n} actual arguments, the +empty list is stored into the location of the last formal argument. +@end table + +The list in @var{variable} or @var{variablen+1} is always newly +created and the procedure can modify it if desired. This is the case +even when the procedure is invoked via @code{apply}, the required part +of the list argument there will be copied (@pxref{Fly Evaluation,, +Procedures for On the Fly Evaluation}). + +@var{body} is a sequence of Scheme expressions which are evaluated in +order when the procedure is invoked. +@end deffn + +@node Primitive Procedures +@subsection Primitive Procedures +@cindex primitives +@cindex primitive procedures + +Procedures written in C can be registered for use from Scheme, +provided they take only arguments of type @code{SCM} and return +@code{SCM} values. @code{scm_c_define_gsubr} is likely to be the most +useful mechanism, combining the process of registration +(@code{scm_c_make_gsubr}) and definition (@code{scm_define}). + +@deftypefun SCM scm_c_make_gsubr (const char *name, int req, int opt, int rst, fcn) +Register a C procedure @var{FCN} as a ``subr'' --- a primitive +subroutine that can be called from Scheme. It will be associated with +the given @var{name} but no environment binding will be created. The +arguments @var{req}, @var{opt} and @var{rst} specify the number of +required, optional and ``rest'' arguments respectively. The total +number of these arguments should match the actual number of arguments +to @var{fcn}. The number of rest arguments should be 0 or 1. +@code{scm_c_make_gsubr} returns a value of type @code{SCM} which is a +``handle'' for the procedure. +@end deftypefun + +@deftypefun SCM scm_c_define_gsubr (const char *name, int req, int opt, int rst, fcn) +Register a C procedure @var{FCN}, as for @code{scm_c_make_gsubr} +above, and additionally create a top-level Scheme binding for the +procedure in the ``current environment'' using @code{scm_define}. +@code{scm_c_define_gsubr} returns a handle for the procedure in the +same way as @code{scm_c_make_gsubr}, which is usually not further +required. +@end deftypefun + +@code{scm_c_make_gsubr} and @code{scm_c_define_gsubr} automatically +use @code{scm_c_make_subr} and also @code{scm_makcclo} if necessary. +It is advisable to use the gsubr variants since they provide a +slightly higher-level abstraction of the Guile implementation. + +@node Optional Arguments +@subsection Optional Arguments + +@c FIXME::martin: Review me! + +Scheme procedures, as defined in R5RS, can either handle a fixed number +of actual arguments, or a fixed number of actual arguments followed by +arbitrarily many additional arguments. Writing procedures of variable +arity can be useful, but unfortunately, the syntactic means for handling +argument lists of varying length is a bit inconvenient. It is possible +to give names to the fixed number of argument, but the remaining +(optional) arguments can be only referenced as a list of values +(@pxref{Lambda}). + +Guile comes with the module @code{(ice-9 optargs)}, which makes using +optional arguments much more convenient. In addition, this module +provides syntax for handling keywords in argument lists +(@pxref{Keywords}). + +Before using any of the procedures or macros defined in this section, +you have to load the module @code{(ice-9 optargs)} with the statement: + +@cindex @code{optargs} +@lisp +(use-modules (ice-9 optargs)) +@end lisp + +@menu +* let-optional Reference:: Locally binding optional arguments. +* let-keywords Reference:: Locally binding keywords arguments. +* lambda* Reference:: Creating advanced argument handling procedures. +* define* Reference:: Defining procedures and macros. +@end menu + + +@node let-optional Reference +@subsubsection let-optional Reference + +@c FIXME::martin: Review me! + +The syntax @code{let-optional} and @code{let-optional*} are for +destructuring rest argument lists and giving names to the various list +elements. @code{let-optional} binds all variables simultaneously, while +@code{let-optional*} binds them sequentially, consistent with @code{let} +and @code{let*} (@pxref{Local Bindings}). + +@deffn {library syntax} let-optional rest-arg (binding @dots{}) expr @dots{} +@deffnx {library syntax} let-optional* rest-arg (binding @dots{}) expr @dots{} +These two macros give you an optional argument interface that is very +@dfn{Schemey} and introduces no fancy syntax. They are compatible with +the scsh macros of the same name, but are slightly extended. Each of +@var{binding} may be of one of the forms @var{var} or @code{(@var{var} +@var{default-value})}. @var{rest-arg} should be the rest-argument of the +procedures these are used from. The items in @var{rest-arg} are +sequentially bound to the variable names are given. When @var{rest-arg} +runs out, the remaining vars are bound either to the default values or +@code{#f} if no default value was specified. @var{rest-arg} remains +bound to whatever may have been left of @var{rest-arg}. + +After binding the variables, the expressions @var{expr} @dots{} are +evaluated in order. +@end deffn + + +@node let-keywords Reference +@subsubsection let-keywords Reference + +@c FIXME::martin: Review me! + +@code{let-keywords} and @code{let-keywords*} are used for extracting +values from argument lists which use keywords instead of argument +position for binding local variables to argument values. + +@code{let-keywords} binds all variables simultaneously, while +@code{let-keywords*} binds them sequentially, consistent with @code{let} +and @code{let*} (@pxref{Local Bindings}). + +@deffn {library syntax} let-keywords rest-arg allow-other-keys? (binding @dots{}) expr @dots{} +@deffnx {library syntax} let-keywords rest-arg allow-other-keys? (binding @dots{}) expr @dots{} +These macros pick out keyword arguments from @var{rest-arg}, but do not +modify it. This is consistent at least with Common Lisp, which +duplicates keyword arguments in the rest argument. More explanation of what +keyword arguments in a lambda list look like can be found below in +the documentation for @code{lambda*} + (@pxref{lambda* Reference}). @var{binding}s can have the same form as +for @code{let-optional}. If @var{allow-other-keys?} is false, an error +will be thrown if anything that looks like a keyword argument but does +not match a known keyword parameter will result in an error. + +After binding the variables, the expressions @var{expr} @dots{} are +evaluated in order. +@end deffn + + +@node lambda* Reference +@subsubsection lambda* Reference + +@c FIXME::martin: Review me! + +When using optional and keyword argument lists, using @code{lambda} for +creating procedures and using @code{let-optional} or @code{let-keywords} +is a bit lengthy. Therefore, @code{lambda*} is provided, which combines +the features of those macros into a single convenient syntax. + +For quick reference, here is the syntax of the formal argument list for +@code{lambda*} (brackets are used to indicate grouping only): + +@example +ext-param-list ::= [identifier]* [#:optional [ext-var-decl]+]? + [#:key [ext-var-decl]+ [#:allow-other-keys]?]? + [[#:rest identifier]|[. identifier]]? + +ext-var-decl ::= identifier | ( identifier expression ) +@end example + +The characters `*', `+' and `?' are not to be taken literally; they mean +respectively, zero or more occurrences, one or more occurrences, and one +or zero occurrences. + +@deffn {library syntax} lambda* formals body +@code{lambda*} creates a procedure that takes optional arguments. These +are specified by putting them inside brackets at the end of the +parameter list, but before any dotted rest argument. For example, + +@lisp +(lambda* (a b #:optional c d . e) '()) +@end lisp + +creates a procedure with fixed arguments @var{a} and @var{b}, optional +arguments @var{c} and @var{d}, and rest argument @var{e}. If the +optional arguments are omitted in a call, the variables for them are +bound to @code{#f}. + +@code{lambda*} can also take keyword arguments. For example, a procedure +defined like this: + +@lisp +(lambda* (#:key xyzzy larch) '()) +@end lisp + +can be called with any of the argument lists @code{(#:xyzzy 11)} +@code{(#:larch 13)} @code{(#:larch 42 #:xyzzy 19)} @code{()}. Whichever +arguments are given as keywords are bound to values. + +Optional and keyword arguments can also be given default values +which they take on when they are not present in a call, by giving a +two-item list in place of an optional argument, for example in: + +@lisp +(lambda* (foo #:optional (bar 42) #:key (baz 73)) + (list foo bar baz)) +@end lisp + +@var{foo} is a fixed argument, @var{bar} is an optional argument with +default value 42, and baz is a keyword argument with default value 73. +Default value expressions are not evaluated unless they are needed and +until the procedure is called. + +@code{lambda*} also supports two more special parameter list keywords. + +@code{lambda*}-defined procedures now throw an error by default if a +keyword other than one of those specified is found in the actual +passed arguments. However, specifying @code{#:allow-other-keys} +immediately after the keyword argument declarations restores the +previous behavior of ignoring unknown keywords. @code{lambda*} also now +guarantees that if the same keyword is passed more than once, the +last one passed is the one that takes effect. For example, + +@lisp +((lambda* (#:key (heads 0) (tails 0)) (display (list heads tails))) + #:heads 37 #:tails 42 #:heads 99) +@end lisp + +would result in (99 47) being displayed. + +@code{#:rest} is also now provided as a synonym for the dotted syntax +rest argument. The argument lists @code{(a . b)} and @code{(a #:rest b)} +are equivalent in all respects to @code{lambda*}. This is provided for +more similarity to DSSSL, MIT-Scheme and Kawa among others, as well as +for refugees from other Lisp dialects. +@end deffn + + +@node define* Reference +@subsubsection define* Reference + +@c FIXME::martin: Review me! + +Just like @code{define} has a shorthand notation for defining procedures +(@pxref{Lambda Alternatives}), @code{define*} is provided as an +abbreviation of the combination of @code{define} and @code{lambda*}. + +@code{define*-public} is the @code{lambda*} version of +@code{define-public}; @code{defmacro*} and @code{defmacro*-public} exist +for defining macros with the improved argument list handling +possibilities. The @code{-public} versions not only define the +procedures/macros, but also export them from the current module. + +@deffn {library syntax} define* formals body +@deffnx {library syntax} define*-public formals body +@code{define*} and @code{define*-public} support optional arguments with +a similar syntax to @code{lambda*}. They also support arbitrary-depth +currying, just like Guile's define. Some examples: + +@lisp +(define* (x y #:optional a (z 3) #:key w . u) + (display (list y z u))) +@end lisp +defines a procedure @code{x} with a fixed argument @var{y}, an optional +argument @var{a}, another optional argument @var{z} with default value 3, +a keyword argument @var{w}, and a rest argument @var{u}. + +@lisp +(define-public* ((foo #:optional bar) #:optional baz) '()) +@end lisp + +This illustrates currying. A procedure @code{foo} is defined, which, +when called with an optional argument @var{bar}, returns a procedure +that takes an optional argument @var{baz}. + +Of course, @code{define*[-public]} also supports @code{#:rest} and +@code{#:allow-other-keys} in the same way as @code{lambda*}. +@end deffn + +@deffn {library syntax} defmacro* name formals body +@deffnx {library syntax} defmacro*-public name formals body +These are just like @code{defmacro} and @code{defmacro-public} except that they +take @code{lambda*}-style extended parameter lists, where @code{#:optional}, +@code{#:key}, @code{#:allow-other-keys} and @code{#:rest} are allowed with the usual +semantics. Here is an example of a macro with an optional argument: + +@lisp +(defmacro* transmorgify (a #:optional b) + (a 1)) +@end lisp +@end deffn + + +@node Procedure Properties +@subsection Procedure Properties and Meta-information + +@c FIXME::martin: Review me! + +Procedures always have attached the environment in which they were +created and information about how to apply them to actual arguments. In +addition to that, properties and meta-information can be stored with +procedures. The procedures in this section can be used to test whether +a given procedure satisfies a condition; and to access and set a +procedure's property. + +The first group of procedures are predicates to test whether a Scheme +object is a procedure, or a special procedure, respectively. +@code{procedure?} is the most general predicates, it returns @code{#t} +for any kind of procedure. @code{closure?} does not return @code{#t} +for primitive procedures, and @code{thunk?} only returns @code{#t} for +procedures which do not accept any arguments. + +@rnindex procedure? +@deffn {Scheme Procedure} procedure? obj +@deffnx {C Function} scm_procedure_p (obj) +Return @code{#t} if @var{obj} is a procedure. +@end deffn + +@deffn {Scheme Procedure} closure? obj +@deffnx {C Function} scm_closure_p (obj) +Return @code{#t} if @var{obj} is a closure. +@end deffn + +@deffn {Scheme Procedure} thunk? obj +@deffnx {C Function} scm_thunk_p (obj) +Return @code{#t} if @var{obj} is a thunk. +@end deffn + +@c FIXME::martin: Is that true? +@cindex procedure properties +Procedure properties are general properties to be attached to +procedures. These can be the name of a procedure or other relevant +information, such as debug hints. + +@deffn {Scheme Procedure} procedure-name proc +@deffnx {C Function} scm_procedure_name (proc) +Return the name of the procedure @var{proc} +@end deffn + +@deffn {Scheme Procedure} procedure-source proc +@deffnx {C Function} scm_procedure_source (proc) +Return the source of the procedure @var{proc}. +@end deffn + +@deffn {Scheme Procedure} procedure-environment proc +@deffnx {C Function} scm_procedure_environment (proc) +Return the environment of the procedure @var{proc}. +@end deffn + +@deffn {Scheme Procedure} procedure-properties proc +@deffnx {C Function} scm_procedure_properties (proc) +Return @var{obj}'s property list. +@end deffn + +@deffn {Scheme Procedure} procedure-property obj key +@deffnx {C Function} scm_procedure_property (obj, key) +Return the property of @var{obj} with name @var{key}. +@end deffn + +@deffn {Scheme Procedure} set-procedure-properties! proc alist +@deffnx {C Function} scm_set_procedure_properties_x (proc, alist) +Set @var{obj}'s property list to @var{alist}. +@end deffn + +@deffn {Scheme Procedure} set-procedure-property! obj key value +@deffnx {C Function} scm_set_procedure_property_x (obj, key, value) +In @var{obj}'s property list, set the property named @var{key} to +@var{value}. +@end deffn + +@cindex procedure documentation +Documentation for a procedure can be accessed with the procedure +@code{procedure-documentation}. + +@deffn {Scheme Procedure} procedure-documentation proc +@deffnx {C Function} scm_procedure_documentation (proc) +Return the documentation string associated with @code{proc}. By +convention, if a procedure contains more than one expression and the +first expression is a string constant, that string is assumed to contain +documentation for that procedure. +@end deffn + +@cindex source properties +@c FIXME::martin: Is the following true? +Source properties are properties which are related to the source code of +a procedure, such as the line and column numbers, the file name etc. + +@deffn {Scheme Procedure} set-source-properties! obj plist +@deffnx {C Function} scm_set_source_properties_x (obj, plist) +Install the association list @var{plist} as the source property +list for @var{obj}. +@end deffn + +@deffn {Scheme Procedure} set-source-property! obj key datum +@deffnx {C Function} scm_set_source_property_x (obj, key, datum) +Set the source property of object @var{obj}, which is specified by +@var{key} to @var{datum}. Normally, the key will be a symbol. +@end deffn + +@deffn {Scheme Procedure} source-properties obj +@deffnx {C Function} scm_source_properties (obj) +Return the source property association list of @var{obj}. +@end deffn + + +@deffn {Scheme Procedure} source-property obj key +@deffnx {C Function} scm_source_property (obj, key) +Return the source property specified by @var{key} from +@var{obj}'s source property list. +@end deffn + + +@node Procedures with Setters +@subsection Procedures with Setters + +@c FIXME::martin: Review me! + +@c FIXME::martin: Document `operator struct'. + +@cindex procedure with setter +@cindex setter +A @dfn{procedure with setter} is a special kind of procedure which +normally behaves like any accessor procedure, that is a procedure which +accesses a data structure. The difference is that this kind of +procedure has a so-called @dfn{setter} attached, which is a procedure +for storing something into a data structure. + +Procedures with setters are treated specially when the procedure appears +in the special form @code{set!} (REFFIXME). How it works is best shown +by example. + +Suppose we have a procedure called @code{foo-ref}, which accepts two +arguments, a value of type @code{foo} and an integer. The procedure +returns the value stored at the given index in the @code{foo} object. +Let @code{f} be a variable containing such a @code{foo} data +structure.@footnote{Working definitions would be: +@lisp +(define foo-ref vector-ref) +(define foo-set! vector-set!) +(define f (make-vector 2 #f)) +@end lisp +} + +@lisp +(foo-ref f 0) @result{} bar +(foo-ref f 1) @result{} braz +@end lisp + +Also suppose that a corresponding setter procedure called +@code{foo-set!} does exist. + +@lisp +(foo-set! f 0 'bla) +(foo-ref f 0) @result{} bla +@end lisp + +Now we could create a new procedure called @code{foo}, which is a +procedure with setter, by calling @code{make-procedure-with-setter} with +the accessor and setter procedures @code{foo-ref} and @code{foo-set!}. +Let us call this new procedure @code{foo}. + +@lisp +(define foo (make-procedure-with-setter foo-ref foo-set!)) +@end lisp + +@code{foo} can from now an be used to either read from the data +structure stored in @code{f}, or to write into the structure. + +@lisp +(set! (foo f 0) 'dum) +(foo f 0) @result{} dum +@end lisp + +@deffn {Scheme Procedure} make-procedure-with-setter procedure setter +@deffnx {C Function} scm_make_procedure_with_setter (procedure, setter) +Create a new procedure which behaves like @var{procedure}, but +with the associated setter @var{setter}. +@end deffn + +@deffn {Scheme Procedure} procedure-with-setter? obj +@deffnx {C Function} scm_procedure_with_setter_p (obj) +Return @code{#t} if @var{obj} is a procedure with an +associated setter procedure. +@end deffn + +@deffn {Scheme Procedure} procedure proc +@deffnx {C Function} scm_procedure (proc) +Return the procedure of @var{proc}, which must be either a +procedure with setter, or an operator struct. +@end deffn + +@deffn {Scheme Procedure} setter proc +Return the setter of @var{proc}, which must be either a procedure with +setter or an operator struct. +@end deffn + + +@node Macros +@subsection Lisp Style Macro Definitions + +@cindex macros +@cindex transformation +Macros are objects which cause the expression that they appear in to be +transformed in some way @emph{before} being evaluated. In expressions +that are intended for macro transformation, the identifier that names +the relevant macro must appear as the first element, like this: + +@lisp +(@var{macro-name} @var{macro-args} @dots{}) +@end lisp + +In Lisp-like languages, the traditional way to define macros is very +similar to procedure definitions. The key differences are that the +macro definition body should return a list that describes the +transformed expression, and that the definition is marked as a macro +definition (rather than a procedure definition) by the use of a +different definition keyword: in Lisp, @code{defmacro} rather than +@code{defun}, and in Scheme, @code{define-macro} rather than +@code{define}. + +@fnindex defmacro +@fnindex define-macro +Guile supports this style of macro definition using both @code{defmacro} +and @code{define-macro}. The only difference between them is how the +macro name and arguments are grouped together in the definition: + +@lisp +(defmacro @var{name} (@var{args} @dots{}) @var{body} @dots{}) +@end lisp + +@noindent +is the same as + +@lisp +(define-macro (@var{name} @var{args} @dots{}) @var{body} @dots{}) +@end lisp + +@noindent +The difference is analogous to the corresponding difference between +Lisp's @code{defun} and Scheme's @code{define}. + +@code{false-if-exception}, from the @file{boot-9.scm} file in the Guile +distribution, is a good example of macro definition using +@code{defmacro}: + +@lisp +(defmacro false-if-exception (expr) + `(catch #t + (lambda () ,expr) + (lambda args #f))) +@end lisp + +@noindent +The effect of this definition is that expressions beginning with the +identifier @code{false-if-exception} are automatically transformed into +a @code{catch} expression following the macro definition specification. +For example: + +@lisp +(false-if-exception (open-input-file "may-not-exist")) +@equiv{} +(catch #t + (lambda () (open-input-file "may-not-exist")) + (lambda args #f)) +@end lisp + + +@node Syntax Rules +@subsection The R5RS @code{syntax-rules} System +@cindex R5RS syntax-rules system + +R5RS defines an alternative system for macro and syntax transformations +using the keywords @code{define-syntax}, @code{let-syntax}, +@code{letrec-syntax} and @code{syntax-rules}. + +The main difference between the R5RS system and the traditional macros +of the previous section is how the transformation is specified. In +R5RS, rather than permitting a macro definition to return an arbitrary +expression, the transformation is specified in a pattern language that + +@itemize @bullet +@item +does not require complicated quoting and extraction of components of the +source expression using @code{caddr} etc. + +@item +is designed such that the bindings associated with identifiers in the +transformed expression are well defined, and such that it is impossible +for the transformed expression to construct new identifiers. +@end itemize + +@noindent +The last point is commonly referred to as being @dfn{hygienic}: the R5RS +@code{syntax-case} system provides @dfn{hygienic macros}. + +For example, the R5RS pattern language for the @code{false-if-exception} +example of the previous section looks like this: + +@lisp +(syntax-rules () + ((_ expr) + (catch #t + (lambda () expr) + (lambda args #f)))) +@end lisp + +@cindex @code{syncase} +In Guile, the @code{syntax-rules} system is provided by the @code{(ice-9 +syncase)} module. To make these facilities available in your code, +include the expression @code{(use-syntax (ice-9 syncase))} (@pxref{Using +Guile Modules}) before the first usage of @code{define-syntax} etc. If +you are writing a Scheme module, you can alternatively include the form +@code{#:use-syntax (ice-9 syncase)} in your @code{define-module} +declaration (@pxref{Creating Guile Modules}). + +@menu +* Pattern Language:: The @code{syntax-rules} pattern language. +* Define-Syntax:: Top level syntax definitions. +* Let-Syntax:: Local syntax definitions. +@end menu + + +@node Pattern Language +@subsubsection The @code{syntax-rules} Pattern Language + + +@node Define-Syntax +@subsubsection Top Level Syntax Definitions + +define-syntax: The gist is + + (define-syntax <keyword> <transformer-spec>) + +makes the <keyword> into a macro so that + + (<keyword> ...) + +expands at _compile_ or _read_ time (i.e. before any +evaluation begins) into some expression that is +given by the <transformer-spec>. + + +@node Let-Syntax +@subsubsection Local Syntax Definitions + + +@node Syntax Case +@subsection Support for the @code{syntax-case} System + + + +@node Internal Macros +@subsection Internal Representation of Macros and Syntax + +Internally, Guile uses three different flavors of macros. The three +flavors are called @dfn{acro} (or @dfn{syntax}), @dfn{macro} and +@dfn{mmacro}. + +Given the expression + +@lisp +(foo @dots{}) +@end lisp + +@noindent +with @code{foo} being some flavor of macro, one of the following things +will happen when the expression is evaluated. + +@itemize @bullet +@item +When @code{foo} has been defined to be an @dfn{acro}, the procedure used +in the acro definition of @code{foo} is passed the whole expression and +the current lexical environment, and whatever that procedure returns is +the value of evaluating the expression. You can think of this a +procedure that receives its argument as an unevaluated expression. + +@item +When @code{foo} has been defined to be a @dfn{macro}, the procedure used +in the macro definition of @code{foo} is passed the whole expression and +the current lexical environment, and whatever that procedure returns is +evaluated again. That is, the procedure should return a valid Scheme +expression. + +@item +When @code{foo} has been defined to be a @dfn{mmacro}, the procedure +used in the mmacro definition of `foo' is passed the whole expression +and the current lexical environment, and whatever that procedure returns +replaces the original expression. Evaluation then starts over from the +new expression that has just been returned. +@end itemize + +The key difference between a @dfn{macro} and a @dfn{mmacro} is that the +expression returned by a @dfn{mmacro} procedure is remembered (or +@dfn{memoized}) so that the expansion does not need to be done again +next time the containing code is evaluated. + +The primitives @code{procedure->syntax}, @code{procedure->macro} and +@code{procedure->memoizing-macro} are used to construct acros, macros +and mmacros respectively. However, if you do not have a very special +reason to use one of these primitives, you should avoid them: they are +very specific to Guile's current implementation and therefore likely to +change. Use @code{defmacro}, @code{define-macro} (@pxref{Macros}) or +@code{define-syntax} (@pxref{Syntax Rules}) instead. (In low level +terms, @code{defmacro}, @code{define-macro} and @code{define-syntax} are +all implemented as mmacros.) + +@deffn {Scheme Procedure} procedure->syntax code +@deffnx {C Function} scm_makacro (code) +Return a macro which, when a symbol defined to this value appears as the +first symbol in an expression, returns the result of applying @var{code} +to the expression and the environment. +@end deffn + +@deffn {Scheme Procedure} procedure->macro code +@deffnx {C Function} scm_makmacro (code) +Return a macro which, when a symbol defined to this value appears as the +first symbol in an expression, evaluates the result of applying +@var{code} to the expression and the environment. For example: + +@lisp +(define trace + (procedure->macro + (lambda (x env) + `(set! ,(cadr x) (tracef ,(cadr x) ',(cadr x)))))) + +(trace @i{foo}) +@equiv{} +(set! @i{foo} (tracef @i{foo} '@i{foo})). +@end lisp +@end deffn + +@deffn {Scheme Procedure} procedure->memoizing-macro code +@deffnx {C Function} scm_makmmacro (code) +Return a macro which, when a symbol defined to this value appears as the +first symbol in an expression, evaluates the result of applying +@var{code} to the expression and the environment. +@code{procedure->memoizing-macro} is the same as +@code{procedure->macro}, except that the expression returned by +@var{code} replaces the original macro expression in the memoized form +of the containing code. +@end deffn + +In the following primitives, @dfn{acro} flavor macros are referred to +as @dfn{syntax transformers}. + +@deffn {Scheme Procedure} macro? obj +@deffnx {C Function} scm_macro_p (obj) +Return @code{#t} if @var{obj} is a regular macro, a memoizing macro or a +syntax transformer. +@end deffn + +@deffn {Scheme Procedure} macro-type m +@deffnx {C Function} scm_macro_type (m) +Return one of the symbols @code{syntax}, @code{macro} or +@code{macro!}, depending on whether @var{m} is a syntax +transformer, a regular macro, or a memoizing macro, +respectively. If @var{m} is not a macro, @code{#f} is +returned. +@end deffn + +@deffn {Scheme Procedure} macro-name m +@deffnx {C Function} scm_macro_name (m) +Return the name of the macro @var{m}. +@end deffn + +@deffn {Scheme Procedure} macro-transformer m +@deffnx {C Function} scm_macro_transformer (m) +Return the transformer of the macro @var{m}. +@end deffn + +@deffn {Scheme Procedure} cons-source xorig x y +@deffnx {C Function} scm_cons_source (xorig, x, y) +Create and return a new pair whose car and cdr are @var{x} and @var{y}. +Any source properties associated with @var{xorig} are also associated +with the new pair. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/api-scheduling.texi b/doc/ref/api-scheduling.texi new file mode 100644 index 000000000..c5e652030 --- /dev/null +++ b/doc/ref/api-scheduling.texi @@ -0,0 +1,863 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Scheduling +@section Threads, Mutexes, Asyncs and Dynamic Roots + +[FIXME: This is pasted in from Tom Lord's original guile.texi chapter +plus the Cygnus programmer's manual; it should be *very* carefully +reviewed and largely reorganized.] + +@menu +* Arbiters:: Synchronization primitives. +* Asyncs:: Asynchronous procedure invocation. +* Dynamic Roots:: Root frames of execution. +* Threads:: Multiple threads of execution. +* Fluids:: Thread-local variables. +* Futures:: Delayed execution in new threads. +* Parallel Forms:: Parallel execution of forms. +@end menu + + +@node Arbiters +@subsection Arbiters + +@cindex arbiters + +@c FIXME::martin: Review me! + +Arbiters are synchronization objects. They are created with +@code{make-arbiter}. Two or more threads can synchronize on an arbiter +by trying to lock it using @code{try-arbiter}. This call will succeed +if no other thread has called @code{try-arbiter} on the arbiter yet, +otherwise it will fail and return @code{#f}. Once an arbiter is +successfully locked, it cannot be locked by another thread until the +thread holding the arbiter calls @code{release-arbiter} to unlock it. + +@deffn {Scheme Procedure} make-arbiter name +@deffnx {C Function} scm_make_arbiter (name) +Return an object of type arbiter and name @var{name}. Its +state is initially unlocked. Arbiters are a way to achieve +process synchronization. +@end deffn + +@deffn {Scheme Procedure} try-arbiter arb +@deffnx {C Function} scm_try_arbiter (arb) +Return @code{#t} and lock the arbiter @var{arb} if the arbiter +was unlocked. Otherwise, return @code{#f}. +@end deffn + +@deffn {Scheme Procedure} release-arbiter arb +@deffnx {C Function} scm_release_arbiter (arb) +Return @code{#t} and unlock the arbiter @var{arb} if the +arbiter was locked. Otherwise, return @code{#f}. +@end deffn + + +@node Asyncs +@subsection Asyncs + +@cindex asyncs +@cindex user asyncs +@cindex system asyncs + +Asyncs are a means of deferring the excution of Scheme code until it is +safe to do so. + +Guile provides two kinds of asyncs that share the basic concept but are +otherwise quite different: system asyncs and user asyncs. System asyncs +are integrated into the core of Guile and are executed automatically +when the system is in a state to allow the execution of Scheme code. +For example, it is not possible to execute Scheme code in a POSIX signal +handler, but such a signal handler can queue a system async to be +executed in the near future, when it is safe to do so. + +System asyncs can also be queued for threads other than the current one. +This way, you can cause threads to asynchronously execute arbitrary +code. + +User asyncs offer a convenient means of queueing procedures for future +execution and triggering this execution. They will not be executed +automatically. + +@menu +* System asyncs:: +* User asyncs:: +@end menu + +@node System asyncs +@subsubsection System asyncs + +To cause the future asynchronous execution of a procedure in a given +thread, use @code{system-async-mark}. + +Automatic invocation of system asyncs can be temporarily disabled by +calling @code{call-with-blocked-asyncs}. This function works by +temporarily increasing the @emph{async blocking level} of the current +thread while a given procedure is running. The blocking level starts +out at zero, and whenever a safe point is reached, a blocking level +greater than zero will prevent the execution of queued asyncs. + +Analogously, the procedure @code{call-with-unblocked-asyncs} will +temporarily decrease the blocking level of the current thread. You +can use it when you want to disable asyncs by default and only allow +them temporarily. + +In addition to the C versions of @code{call-with-blocked-asyncs} and +@code{call-with-unblocked-asyncs}, C code can use +@code{scm_with_blocked_asyncs} and @code{scm_with_unblocked_asyncs} +inside a @dfn{frame} (@pxref{Frames}) to block or unblock system asyncs +temporarily. + +@deffn {Scheme Procedure} system-async-mark proc [thread] +@deffnx {C Function} scm_system_async_mark (proc) +@deffnx {C Function} scm_system_async_mark_for_thread (proc, thread) +Mark @var{proc} (a procedure with zero arguments) for future execution +in @var{thread}. When @var{proc} has already been marked for +@var{thread} but has not been executed yet, this call has no effect. +When @var{thread} is omitted, the thread that called +@code{system-async-mark} is used. + +This procedure is not safe to be called from signal handlers. Use +@code{scm_sigaction} or @code{scm_sigaction_for_thread} to install +signal handlers. +@end deffn + +@c FIXME: The use of @deffnx for scm_c_call_with_blocked_asyncs and +@c scm_c_call_with_unblocked_asyncs puts "void" into the function +@c index. Would prefer to use @deftypefnx if makeinfo allowed that, +@c or a @deftypefn with an empty return type argument if it didn't +@c introduce an extra space. + +@deffn {Scheme Procedure} call-with-blocked-asyncs proc +@deffnx {C Function} scm_call_with_blocked_asyncs (proc) +@deffnx {C Function} void *scm_c_call_with_blocked_asyncs (void * (*proc) (void *data), void *data) +@findex scm_c_call_with_blocked_asyncs +Call @var{proc} and block the execution of system asyncs by one level +for the current thread while it is running. Return the value returned +by @var{proc}. For the first two variants, call @var{proc} with no +arguments; for the third, call it with @var{data}. +@end deffn + +@deffn {Scheme Procedure} call-with-unblocked-asyncs proc +@deffnx {C Function} scm_call_with_unblocked_asyncs (proc) +@deffnx {C Function} void *scm_c_call_with_unblocked_asyncs (void *(*p) (void *d), void *d) +@findex scm_c_call_with_unblocked_asyncs +Call @var{proc} and unblock the execution of system asyncs by one +level for the current thread while it is running. Return the value +returned by @var{proc}. For the first two variants, call @var{proc} +with no arguments; for the third, call it with @var{data}. +@end deffn + +@deftypefn {C Function} void scm_frame_block_asyncs () +This function must be used inside a pair of calls to +@code{scm_frame_begin} and @code{scm_frame_end} (@pxref{Frames}). +During the dynamic extent of the frame, asyncs are blocked by one level. +@end deftypefn + +@deftypefn {C Function} void scm_frame_unblock_asyncs () +This function must be used inside a pair of calls to +@code{scm_frame_begin} and @code{scm_frame_end} (@pxref{Frames}). +During the dynamic extent of the frame, asyncs are unblocked by one +level. +@end deftypefn + +@node User asyncs +@subsubsection User asyncs + +A user async is a pair of a thunk (a parameterless procedure) and a +mark. Setting the mark on a user async will cause the thunk to be +executed when the user async is passed to @code{run-asyncs}. Setting +the mark more than once is satisfied by one execution of the thunk. + +User asyncs are created with @code{async}. They are marked with +@code{async-mark}. + +@deffn {Scheme Procedure} async thunk +@deffnx {C Function} scm_async (thunk) +Create a new user async for the procedure @var{thunk}. +@end deffn + +@deffn {Scheme Procedure} async-mark a +@deffnx {C Function} scm_async_mark (a) +Mark the user async @var{a} for future execution. +@end deffn + +@deffn {Scheme Procedure} run-asyncs list_of_a +@deffnx {C Function} scm_run_asyncs (list_of_a) +Execute all thunks from the marked asyncs of the list @var{list_of_a}. +@end deffn + + +@node Dynamic Roots +@subsection Dynamic Roots +@cindex dynamic roots + +A @dfn{dynamic root} is a root frame of Scheme evaluation. +The top-level repl, for example, is an instance of a dynamic root. + +Each dynamic root has its own chain of dynamic-wind information. Each +has its own set of continuations, jump-buffers, and pending CATCH +statements which are inaccessible from the dynamic scope of any +other dynamic root. + +In a thread-based system, each thread has its own dynamic root. Therefore, +continuations created by one thread may not be invoked by another. + +Even in a single-threaded system, it is sometimes useful to create a new +dynamic root. For example, if you want to apply a procedure, but to +not allow that procedure to capture the current continuation, calling +the procedure under a new dynamic root will do the job. + +@deffn {Scheme Procedure} call-with-dynamic-root thunk handler +@deffnx {C Function} scm_call_with_dynamic_root (thunk, handler) +Evaluate @code{(thunk)} in a new dynamic context, returning its value. + +If an error occurs during evaluation, apply @var{handler} to the +arguments to the throw, just as @code{throw} would. If this happens, +@var{handler} is called outside the scope of the new root -- it is +called in the same dynamic context in which +@code{call-with-dynamic-root} was evaluated. + +If @var{thunk} captures a continuation, the continuation is rooted at +the call to @var{thunk}. In particular, the call to +@code{call-with-dynamic-root} is not captured. Therefore, +@code{call-with-dynamic-root} always returns at most one time. + +Before calling @var{thunk}, the dynamic-wind chain is un-wound back to +the root and a new chain started for @var{thunk}. Therefore, this call +may not do what you expect: + +@lisp +;; Almost certainly a bug: +(with-output-to-port + some-port + + (lambda () + (call-with-dynamic-root + (lambda () + (display 'fnord) + (newline)) + (lambda (errcode) errcode)))) +@end lisp + +The problem is, on what port will @samp{fnord} be displayed? You +might expect that because of the @code{with-output-to-port} that +it will be displayed on the port bound to @code{some-port}. But it +probably won't -- before evaluating the thunk, dynamic winds are +unwound, including those created by @code{with-output-to-port}. +So, the standard output port will have been re-set to its default value +before @code{display} is evaluated. + +(This function was added to Guile mostly to help calls to functions in C +libraries that can not tolerate non-local exits or calls that return +multiple times. If such functions call back to the interpreter, it should +be under a new dynamic root.) +@end deffn + + +@deffn {Scheme Procedure} dynamic-root +@deffnx {C Function} scm_dynamic_root () +Return an object representing the current dynamic root. + +These objects are only useful for comparison using @code{eq?}. +They are currently represented as numbers, but your code should +in no way depend on this. +@end deffn + +@c begin (scm-doc-string "boot-9.scm" "quit") +@deffn {Scheme Procedure} quit [exit_val] +Throw back to the error handler of the current dynamic root. + +If integer @var{exit_val} is specified and if Guile is being used +stand-alone and if quit is called from the initial dynamic-root, +@var{exit_val} becomes the exit status of the Guile process and the +process exits. +@end deffn + +When Guile is run interactively, errors are caught from within the +read-eval-print loop. An error message will be printed and @code{abort} +called. A default set of signal handlers is installed, e.g., to allow +user interrupt of the interpreter. + +It is possible to switch to a "batch mode", in which the interpreter +will terminate after an error and in which all signals cause their +default actions. Switching to batch mode causes any handlers installed +from Scheme code to be removed. An example of where this is useful is +after forking a new process intended to run non-interactively. + +@c begin (scm-doc-string "boot-9.scm" "batch-mode?") +@deffn {Scheme Procedure} batch-mode? +Returns a boolean indicating whether the interpreter is in batch mode. +@end deffn + +@c begin (scm-doc-string "boot-9.scm" "set-batch-mode?!") +@deffn {Scheme Procedure} set-batch-mode?! arg +If @var{arg} is true, switches the interpreter to batch mode. +The @code{#f} case has not been implemented. +@end deffn + +@node Threads +@subsection Threads +@cindex threads +@cindex Guile threads +@cindex POSIX threads + +Guile threads are implemented using POSIX threads, they run +pre-emptively and concurrently through both Scheme code and system +calls. The only exception is for garbage collection, where all +threads must rendezvous. + +@menu +* Low level thread primitives:: +* Higher level thread procedures:: +* C level thread interface:: +@end menu + + +@node Low level thread primitives +@subsubsection Low level thread primitives + +@c NJFIXME no current mechanism for making sure that these docstrings +@c are in sync. + +@c begin (texi-doc-string "guile" "call-with-new-thread") +@deffn {Scheme Procedure} call-with-new-thread thunk error-handler +Evaluate @code{(thunk)} in a new thread, and new dynamic context, +returning a new thread object representing the thread. + +If an error occurs during evaluation, call error-handler, passing it +an error code. If this happens, the error-handler is called outside +the scope of the new root -- it is called in the same dynamic context +in which with-new-thread was evaluated, but not in the caller's +thread. + +All the evaluation rules for dynamic roots apply to threads. +@end deffn + +@c begin (texi-doc-string "guile" "join-thread") +@deffn {Scheme Procedure} join-thread thread +Suspend execution of the calling thread until the target @var{thread} +terminates, unless the target @var{thread} has already terminated. +@end deffn + +@c begin (texi-doc-string "guile" "yield") +@deffn {Scheme Procedure} yield +If one or more threads are waiting to execute, calling yield forces an +immediate context switch to one of them. Otherwise, yield has no effect. +@end deffn + +@c begin (texi-doc-string "guile" "make-mutex") +@deffn {Scheme Procedure} make-mutex +Create a new mutex object. +@end deffn + +@c begin (texi-doc-string "guile" "lock-mutex") +@deffn {Scheme Procedure} lock-mutex mutex +Lock @var{mutex}. If the mutex is already locked, the calling thread +blocks until the mutex becomes available. The function returns when +the calling thread owns the lock on @var{mutex}. Locking a mutex that +a thread already owns will succeed right away and will not block the +thread. That is, Guile's mutexes are @emph{recursive}. + +When a system async is activated for a thread that is blocked in a +call to @code{lock-mutex}, the waiting is interrupted and the async is +executed. When the async returns, the waiting is resumed. +@end deffn + +@deffn {Scheme Procedure} try-mutex mutex +Try to lock @var{mutex}. If the mutex is already locked by someone +else, return @code{#f}. Else lock the mutex and return @code{#t}. +@end deffn + +@c begin (texi-doc-string "guile" "unlock-mutex") +@deffn {Scheme Procedure} unlock-mutex mutex +Unlocks @var{mutex} if the calling thread owns the lock on +@var{mutex}. Calling unlock-mutex on a mutex not owned by the current +thread results in undefined behaviour. Once a mutex has been unlocked, +one thread blocked on @var{mutex} is awakened and grabs the mutex +lock. Every call to @code{lock-mutex} by this thread must be matched +with a call to @code{unlock-mutex}. Only the last call to +@code{unlock-mutex} will actually unlock the mutex. +@end deffn + +@c begin (texi-doc-string "guile" "make-condition-variable") +@deffn {Scheme Procedure} make-condition-variable +Make a new condition variable. +@end deffn + +@c begin (texi-doc-string "guile" "wait-condition-variable") +@deffn {Scheme Procedure} wait-condition-variable cond-var mutex [time] +Wait until @var{cond-var} has been signalled. While waiting, +@var{mutex} is atomically unlocked (as with @code{unlock-mutex}) and +is locked again when this function returns. When @var{time} is given, +it specifies a point in time where the waiting should be aborted. It +can be either a integer as returned by @code{current-time} or a pair +as returned by @code{gettimeofday}. When the waiting is aborted, +@code{#f} is returned. When the condition variable has in fact been +signalled, @code{#t} is returned. The mutex is re-locked in any case +before @code{wait-condition-variable} returns. + +When a system async is activated for a thread that is blocked in a +call to @code{wait-condition-variable}, the waiting is interrupted, +the mutex is locked, and the async is executed. When the async +returns, the mutex is unlocked again and the waiting is resumed. +@end deffn + +@c begin (texi-doc-string "guile" "signal-condition-variable") +@deffn {Scheme Procedure} signal-condition-variable cond-var +Wake up one thread that is waiting for @var{cv}. +@end deffn + +@c begin (texi-doc-string "guile" "broadcast-condition-variable") +@deffn {Scheme Procedure} broadcast-condition-variable cond-var +Wake up all threads that are waiting for @var{cv}. +@end deffn + +@node Higher level thread procedures +@subsubsection Higher level thread procedures + +@c new by ttn, needs review + +Higher level thread procedures are available by loading the +@code{(ice-9 threads)} module. These provide standardized +thread creation and mutex interaction. + +@deffn macro make-thread proc [args@dots{}] +Apply @var{proc} to @var{args} in a new thread formed by +@code{call-with-new-thread} using a default error handler that display +the error to the current error port. +@end deffn + +@deffn macro begin-thread first [rest@dots{}] +Evaluate forms @var{first} and @var{rest} in a new thread formed by +@code{call-with-new-thread} using a default error handler that display +the error to the current error port. +@end deffn + +@deffn macro with-mutex m [body@dots{}] +Lock mutex @var{m}, evaluate @var{body}, and then unlock @var{m}. +These sub-operations form the branches of a @code{dynamic-wind}. +@end deffn + +@deffn macro monitor body@dots{} +Evaluate @var{body}, with a mutex locked so only one thread can +execute that code at any one time. Each @code{monitor} form has its +own private mutex and the locking is done as per @code{with-mutex} +above. The return value is the return from the last form in +@var{body}. + +The term ``monitor'' comes from operating system theory, where it +means a particular bit of code managing access to some resource and +which only ever executes on behalf of one process at any one time. +@end deffn + +@node C level thread interface +@subsubsection C level thread interface + +You can create and manage threads, mutexes, and condition variables +with the C versions of the primitives above. For example, you can +create a mutex with @code{scm_make_mutex} and lock it with +@code{scm_lock_mutex}. In addition to these primitives there is also +a second set of primitives for threading related things. These +functions and data types are only available from C and can not be +mixed with the first set from above. However, they might be more +efficient and can be used in situations where Scheme data types are +not allowed or are inconvenient to use. + +Furthermore, they are the primitives that Guile relies on for its own +higher level threads. By reimplementing them, you can adapt Guile to +different low-level thread implementations. + +C code in a thread must call a libguile function periodically. When +one thread finds garbage collection is required, it waits for all +threads to rendezvous before doing that GC. Such a rendezvous is +checked within libguile functions. If C code wants to sleep or block +in a thread it should use one of the libguile functions provided. + +Only threads created by Guile can use the libguile functions. Threads +created directly with say @code{pthread_create} are unknown to Guile +and they cannot call libguile. The stack in such foreign threads is +not scanned during GC, so @code{SCM} values generally cannot be held +there. + +@c FIXME: +@c +@c Describe SCM_TICK which can be called if no other libguile +@c function is being used by a C function. +@c +@c Describe "Guile mode", which a thread can enter and exit. There +@c are no functions for doing this yet. +@c +@c When in guile mode a thread can call libguile, is subject to the +@c tick rule, and its stack is scanned. When not in guile mode it +@c cannot call libguile, it doesn't have to tick, and its stack is +@c not scanned. The strange guile control flow things like +@c exceptions, continuations and asyncs only occur when in guile +@c mode. +@c +@c When guile mode is exited, the portion of the stack allocated +@c while it was in guile mode is still scanned. This portion may not +@c be modified when outside guile mode. The stack ends up +@c partitioned into alternating guile and non-guile regions. +@c +@c Leaving guile mode is convenient when running an extended +@c calculation not involving guile, since one doesn't need to worry +@c about SCM_TICK calls. + + +@deftp {C Data Type} scm_t_thread +This data type represents a thread, to be used with scm_thread_create, +etc. +@end deftp + +@deftypefn {C Function} int scm_thread_create (scm_t_thread *t, void (*proc)(void *), void *data) +Create a new thread that will start by calling @var{proc}, passing it +@var{data}. A handle for the new thread is stored in @var{t}, which +must be non-NULL. The thread terminated when @var{proc} returns. +When the thread has not been detached, its handle remains valid after +is has terminated so that it can be used with @var{scm_thread_join}, +for example. When it has been detached, the handle becomes invalid as +soon as the thread terminates. +@end deftypefn + +@deftypefn {C Function} void scm_thread_detach (scm_t_thread t) +Detach the thread @var{t}. See @code{scm_thread_create}. +@end deftypefn + +@deftypefn {C Function} void scm_thread_join (scm_t_thread t) +Wait for thread @var{t} to terminate. The thread must not have been +detached at the time that @code{scm_thread_join} is called, but it +might have been detached by the time it terminates. +@end deftypefn + +@deftypefn {C Function} scm_t_thread scm_thread_self () +Return the handle of the calling thread. +@end deftypefn + +@deftp {C Data Type} scm_t_mutex +This data type represents a mutex, to be used with scm_mutex_init, +etc. +@end deftp + +@deftypefn {C Function} void scm_mutex_init (scm_t_mutex *m) +Initialize the mutex structure pointed to by @var{m}. +@end deftypefn + +@deftypefn {C Function} void scm_mutex_destroy (scm_t_mutex *m) +Deallocate all resources associated with @var{m}. +@end deftypefn + +@deftypefn {C Function} void scm_mutex_lock (scm_t_mutex *m) +Lock the mutex @var{m}. When it is already locked by a different +thread, wait until it becomes available. Locking a mutex that is +already locked by the current threads is not allowd and results in +undefined behavior. The mutices are not guaranteed to be fair. That +is, a thread that attempts a lock after yourself might be granted it +before you. +@end deftypefn + +@deftypefn {C Function} int scm_mutex_trylock (scm_t_mutex *m) +Lock @var{m} as with @code{scm_mutex_lock} but don't wait when this +does succeed immediately. Returns non-zero when the mutex could in +fact be locked , and zero when it is already locked by some other +thread. +@end deftypefn + +@deftypefn {C Function} void scm_mutex_unlock (scm_t_mutex *m) +Unlock the mutex @var{m}. The mutex must have been locked by the +current thread, else the behavior is undefined. +@end deftypefn + +@deftp {C Data Type} scm_t_cond +This data type represents a condition variable, to be used with +scm_cond_init, etc. +@end deftp + +@deftypefn {C Function} void scm_cond_init (scm_t_cond *c) +Initialize the mutex structure pointed to by @var{c}. +@end deftypefn + +@deftypefn {C Function} void scm_cond_destroy (scm_t_cond *c) +Deallocate all resources associated with @var{c}. +@end deftypefn + +@deftypefn {C Function} void scm_cond_wait (scm_t_cond *c, scm_t_mutex *m) +Wait for @var{c} to be signalled. While waiting @var{m} is unlocked +and locked again before @code{scm_cond_wait} returns. +@end deftypefn + +@deftypefn {C Function} void scm_cond_timedwait (scm_t_cond *c, scm_t_mutex *m, timespec *abstime) +Wait for @var{c} to be signalled as with @code{scm_cond_wait} but +don't wait longer than the point in time specified by @var{abstime}. +when the waiting is aborted, zero is returned; non-zero else. +@end deftypefn + +@deftypefn {C Function} void scm_cond_signal (scm_t_cond *c) +Signal the condition variable @var{c}. When one or more threads are +waiting for it to be signalled, select one arbitrarily and let its +wait succeed. +@end deftypefn + +@deftypefn {C Function} void scm_cond_broadcast (scm_t_cond *c) +Signal the condition variable @var{c}. When there are threads waiting +for it to be signalled, wake them all up and make all their waits +succeed. +@end deftypefn + +@deftp {C Type} scm_t_key +This type represents a key for a thread-specific value. +@end deftp + +@deftypefn {C Function} void scm_key_create (scm_t_key *keyp) +Create a new key for a thread-specific value. Each thread has its own +value associated to such a handle. The new handle is stored into +@var{keyp}, which must be non-NULL. +@end deftypefn + +@deftypefn {C Function} void scm_key_delete (scm_t_key key) +This function makes @var{key} invalid as a key for thread-specific data. +@end deftypefn + +@deftypefn {C Function} void scm_key_setspecific (scm_t_key key, const void *value) +Associate @var{value} with @var{key} in the calling thread. +@end deftypefn + +@deftypefn {C Function} int scm_key_getspecific (scm_t_key key) +Return the value currently associated with @var{key} in the calling +thread. When @code{scm_key_setspecific} has not yet been called in +this thread with this key, @code{NULL} is returned. +@end deftypefn + +@deftypefn {C Function} int scm_thread_select (...) +This function does the same thing as the system's @code{select} +function, but in a way that is friendly to the thread implementation. +You should call it in preference to the system @code{select}. +@end deftypefn + +@node Fluids +@subsection Fluids + +@cindex fluids + +Fluids are objects to store values in. They have a few properties +which make them useful in certain situations: Fluids can have one +value per dynamic root (@pxref{Dynamic Roots}), so that changes to the +value in a fluid are only visible in the same dynamic root. Since +threads are executed in separate dynamic roots, fluids can be used for +thread local storage (@pxref{Threads}). + +Fluids can be used to simulate the desirable effects of dynamically +scoped variables. Dynamically scoped variables are useful when you +want to set a variable to a value during some dynamic extent in the +execution of your program and have them revert to their original value +when the control flow is outside of this dynamic extent. See the +description of @code{with-fluids} below for details. + +New fluids are created with @code{make-fluid} and @code{fluid?} is +used for testing whether an object is actually a fluid. The values +stored in a fluid can be accessed with @code{fluid-ref} and +@code{fluid-set!}. + +@deffn {Scheme Procedure} make-fluid +@deffnx {C Function} scm_make_fluid () +Return a newly created fluid. +Fluids are objects of a certain type (a smob) that can hold one SCM +value per dynamic root. That is, modifications to this value are +only visible to code that executes within the same dynamic root as +the modifying code. When a new dynamic root is constructed, it +inherits the values from its parent. Because each thread executes +in its own dynamic root, you can use fluids for thread local storage. +@end deffn + +@deffn {Scheme Procedure} fluid? obj +@deffnx {C Function} scm_fluid_p (obj) +Return @code{#t} iff @var{obj} is a fluid; otherwise, return +@code{#f}. +@end deffn + +@deffn {Scheme Procedure} fluid-ref fluid +@deffnx {C Function} scm_fluid_ref (fluid) +Return the value associated with @var{fluid} in the current +dynamic root. If @var{fluid} has not been set, then return +@code{#f}. +@end deffn + +@deffn {Scheme Procedure} fluid-set! fluid value +@deffnx {C Function} scm_fluid_set_x (fluid, value) +Set the value associated with @var{fluid} in the current dynamic root. +@end deffn + +@code{with-fluids*} temporarily changes the values of one or more fluids, +so that the given procedure and each procedure called by it access the +given values. After the procedure returns, the old values are restored. + +@deffn {Scheme Procedure} with-fluids* fluids values thunk +@deffnx {C Function} scm_with_fluids (fluids, values, thunk) +Set @var{fluids} to @var{values} temporary, and call @var{thunk}. +@var{fluids} must be a list of fluids and @var{values} must be the +same number of their values to be applied. Each substitution is done +in the order given. @var{thunk} must be a procedure with no argument. +it is called inside a @code{dynamic-wind} and the fluids are +set/restored when control enter or leaves the established dynamic +extent. +@end deffn + +@deffn {Scheme Macro} with-fluids ((fluid value) ...) body... +Execute @var{body...} while each @var{fluid} is set to the +corresponding @var{value}. Both @var{fluid} and @var{value} are +evaluated and @var{fluid} must yield a fluid. @var{body...} is +executed inside a @code{dynamic-wind} and the fluids are set/restored +when control enter or leaves the established dynamic extent. +@end deffn + +@deftypefn {C Function} SCM scm_c_with_fluids (SCM fluids, SCM vals, SCM (*cproc)(void *), void *data) +@deftypefnx {C Function} SCM scm_c_with_fluid (SCM fluid, SCM val, SCM (*cproc)(void *), void *data) +The function @code{scm_c_with_fluids} is like @code{scm_with_fluids} +except that it takes a C function to call instead of a Scheme thunk. + +The function @code{scm_c_with_fluid} is similar but only allows one +fluid to be set instead of a list. +@end deftypefn + +@deftypefn {C Function} void scm_frame_fluid (SCM fluid, SCM val) +This function must be used inside a pair of calls to +@code{scm_frame_begin} and @code{scm_frame_end} (@pxref{Frames}). +During the dynamic extent of the frame, the fluid @var{fluid} is set +to @var{val}. + +More precisely, the value of the fluid is swapped with a `backup' +value whenever the frame is entered or left. The backup value is +initialized with the @var{val} argument. +@end deftypefn + +@node Futures +@subsection Futures +@cindex futures + +Futures are a convenient way to run a calculation in a new thread, and +only wait for the result when it's actually needed. + +Futures are similar to promises (@pxref{Delayed Evaluation}), in that +they allow mainline code to continue immediately. But @code{delay} +doesn't evaluate at all until forced, whereas @code{future} starts +immediately in a new thread. + +@deffn {syntax} future expr +Begin evaluating @var{expr} in a new thread, and return a ``future'' +object representing the calculation. +@end deffn + +@deffn {Scheme Procedure} make-future thunk +@deffnx {C Function} scm_make_future (thunk) +Begin evaluating the call @code{(@var{thunk})} in a new thread, and +return a ``future'' object representing the calculation. +@end deffn + +@deffn {Scheme Procedure} future-ref f +@deffnx {C Function} scm_future_ref (f) +Return the value computed by the future @var{f}. If @var{f} has not +yet finished executing then wait for it to do so. +@end deffn + + +@node Parallel Forms +@subsection Parallel forms +@cindex parallel forms + +The functions described in this section are available from + +@example +(use-modules (ice-9 threads)) +@end example + +@deffn syntax parallel expr1 @dots{} exprN +Evaluate each @var{expr} expression in parallel, each in a new thread. +Return the results as a set of @var{N} multiple values +(@pxref{Multiple Values}). +@end deffn + +@deffn syntax letpar ((var1 expr1) @dots{} (varN exprN)) body@dots{} +Evaluate each @var{expr} in parallel, each in a new thread, then bind +the results to the corresponding @var{var} variables and evaluate +@var{body}. + +@code{letpar} is like @code{let} (@pxref{Local Bindings}), but all the +expressions for the bindings are evaluated in parallel. +@end deffn + +@deffn {Scheme Procedure} par-map proc lst1 @dots{} lstN +@deffnx {Scheme Procedure} par-for-each proc lst1 @dots{} lstN +Call @var{proc} on the elements of the given lists. @code{par-map} +returns a list comprising the return values from @var{proc}. +@code{par-for-each} returns an unspecified value, but waits for all +calls to complete. + +The @var{proc} calls are @code{(@var{proc} @var{elem1} @dots{} +@var{elemN})}, where each @var{elem} is from the corresponding +@var{lst}. Each @var{lst} must be the same length. The calls are +made in parallel, each in a new thread. + +These functions are like @code{map} and @code{for-each} (@pxref{List +Mapping}), but make their @var{proc} calls in parallel. +@end deffn + +@deffn {Scheme Procedure} n-par-map n proc lst1 @dots{} lstN +@deffnx {Scheme Procedure} n-par-for-each n proc lst1 @dots{} lstN +Call @var{proc} on the elements of the given lists, in the same way as +@code{par-map} and @code{par-for-each} above, but use no more than +@var{n} new 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 +@var{proc} calls might be costly, or if there are many to be made. On +a dual-CPU system for instance @math{@var{n}=4} might be enough to +keep the CPUs utilized, and not consume too much memory. +@end deffn + +@deffn {Scheme Procedure} n-for-each-par-map n sproc pproc lst1 @dots{} lstN +Apply @var{pproc} to the elements of the given lists, and apply +@var{sproc} to each result returned by @var{pproc}. The final return +value is unspecified, but all calls will have been completed before +returning. + +The calls made are @code{(@var{sproc} (@var{pproc} @var{elem1} @dots{} +@var{elemN}))}, where each @var{elem} is from the corresponding +@var{lst}. Each @var{lst} must have the same number of elements. + +The @var{pproc} calls are made in parallel, in new threads. No more +than @var{n} new threads are used at any one time. The order in which +@var{pproc} calls are initiated within that limit is unspecified. + +The @var{sproc} calls are made serially, in list element order, one at +a time. @var{pproc} calls on later elements may execute in parallel +with the @var{sproc} calls. Exactly which thread makes each +@var{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 @var{n} limit on threads +controls system resource usage when there are many calculations or +when they might be costly. + +It will be seen that @code{n-for-each-par-map} is like a combination +of @code{n-par-map} and @code{for-each}, + +@example +(for-each sproc (n-par-map pproc lst1 ... lstN)) +@end example + +@noindent +But the actual implementation is more efficient since each @var{sproc} +call, in turn, can be initiated once the relevant @var{pproc} call has +completed, it doesn't need to wait for all to finish. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/api-scm.texi b/doc/ref/api-scm.texi new file mode 100644 index 000000000..54bb3eb3f --- /dev/null +++ b/doc/ref/api-scm.texi @@ -0,0 +1,45 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + + +@node The SCM Type +@section The SCM Type + +Guile represents all Scheme values with the single C type @code{SCM}. +For an introduction to this topic, @xref{Dynamic Types}. + +@deftp {C Type} SCM +@code{SCM} is the user level abstract C type that is used to represent +all of Guile's Scheme objects, no matter what the Scheme object type is. +No C operation except assignment is guaranteed to work with variables of +type @code{SCM}, so you should only use macros and functions to work +with @code{SCM} values. Values are converted between C data types and +the @code{SCM} type with utility functions and macros. +@end deftp +@cindex SCM data type + +@deftp {C Type} scm_t_bits +@code{scm_t_bits} is an unsigned integral data type that is guaranteed +to be large enough to hold all information that is required to +represent any Scheme object. While this data type is mostly used to +implement Guile's internals, the use of this type is also necessary to +write certain kinds of extensions to Guile. +@end deftp + +@deftp {C Type} scm_t_signed_bits +This is a signed integral type of the same size as @code{scm_t_bits}. +@end deftp + +@deftypefn {C Macro} scm_t_bits SCM_UNPACK (SCM @var{x}) +Transforms the @code{SCM} value @var{x} into its representation as an +integral type. Only after applying @code{SCM_UNPACK} it is possible to +access the bits and contents of the @code{SCM} value. +@end deftypefn + +@deftypefn {C Macro} SCM SCM_PACK (scm_t_bits @var{x}) +Takes a valid integral representation of a Scheme object and transforms +it into its representation as a @code{SCM} value. +@end deftypefn diff --git a/doc/ref/api-smobs.texi b/doc/ref/api-smobs.texi new file mode 100644 index 000000000..fd6232866 --- /dev/null +++ b/doc/ref/api-smobs.texi @@ -0,0 +1,185 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Smobs +@section Smobs + +This chapter contains reference information related to defining and +working with smobs. See @ref{Defining New Types (Smobs)} for a +tutorial-like introduction to smobs. + +@deftypefun scm_t_bits scm_make_smob_type (const char *name, size_t size) +This function adds a new smob type, named @var{name}, with instance size +@var{size}, to the system. The return value is a tag that is used in +creating instances of the type. + +If @var{size} is 0, the default @emph{free} function will do nothing. + +If @var{size} is not 0, the default @emph{free} function will +deallocate the memory block pointed to by @code{SCM_SMOB_DATA} with +@code{scm_gc_free}. The @var{WHAT} parameter in the call to +@code{scm_gc_free} will be @var{NAME}. + +Default values are provided for the @emph{mark}, @emph{free}, +@emph{print}, and @emph{equalp} functions, as described in +@ref{Defining New Types (Smobs)}. If you want to customize any of +these functions, the call to @code{scm_make_smob_type} should be +immediately followed by calls to one or several of +@code{scm_set_smob_mark}, @code{scm_set_smob_free}, +@code{scm_set_smob_print}, and/or @code{scm_set_smob_equalp}. +@end deftypefun + +@deftypefn {C Function} void scm_set_smob_mark (scm_t_bits tc, SCM (*mark) (SCM obj)) +This function sets the smob marking procedure for the smob type specified by +the tag @var{tc}. @var{tc} is the tag returned by @code{scm_make_smob_type}. + +The @var{mark} procedure must cause @code{scm_gc_mark} to be called +for every @code{SCM} value that is directly referenced by the smob +instance @var{obj}. One of these @code{SCM} values can be returned +from the procedure and Guile will call @code{scm_gc_mark} for it. +This can be used to avoid deep recursions for smob instances that form +a list. +@end deftypefn + +@deftypefn {C Function} void scm_set_smob_free (scm_t_bits tc, size_t (*free) (SCM obj)) +This function sets the smob freeing procedure for the smob type +specified by the tag @var{tc}. @var{tc} is the tag returned by +@code{scm_make_smob_type}. + +The @var{free} procedure must deallocate all resources that are +directly associated with the smob instance @var{OBJ}. It must assume +that all @code{SCM} values that it references have already been freed +and are thus invalid. + +The @var{free} procedure must return 0. +@end deftypefn + +@deftypefn {C Function} void scm_set_smob_print (scm_t_bits tc, int (*print) (SCM obj, SCM port, scm_print_state* pstate)) +This function sets the smob printing procedure for the smob type +specified by the tag @var{tc}. @var{tc} is the tag returned by +@code{scm_make_smob_type}. + +The @var{print} procedure should output a textual representation of +the smob instance @var{obj} to @var{port}, using information in +@var{pstate}. + +The textual representation should be of the form @code{#<name ...>}. +This ensures that @code{read} will not interpret it as some other +Scheme value. + +It is often best to ignore @var{pstate} and just print to @var{port} +with @code{scm_display}, @code{scm_write}, @code{scm_simple_format}, +and @code{scm_puts}. +@end deftypefn + +@deftypefn {C Function} void scm_set_smob_equalp (scm_t_bits tc, SCM (*equalp) (SCM obj1, SCM obj1)) +This function sets the smob equality-testing predicate for the smob +type specified by the tag @var{tc}. @var{tc} is the tag returned by +@code{scm_make_smob_type}. + +The @var{equalp} procedure should return @code{SCM_BOOL_T} when +@var{obj1} is @code{equal?} to @var{obj2}. Else it should return +@var{SCM_BOOL_F}. Both @var{obj1} and @var{obj2} are instances of the +smob type @var{tc}. +@end deftypefn + +@deftypefn {C Macro} int SCM_SMOB_PREDICATE (scm_t_bits tag, SCM exp) +Return true iff @var{exp} is a smob instance of the type indicated by +@var{tag}. The expression @var{exp} can be evaluated more than once, +so it shouldn't contain any side effects. +@end deftypefn + +@deftypefn {C Macro} void SCM_NEWSMOB (SCM value, scm_t_bits tag, void *data) +@deftypefnx {C Macro} void SCM_NEWSMOB2 (SCM value, scm_t_bits tag, void *data, void *data2) +@deftypefnx {C Macro} void SCM_NEWSMOB3 (SCM value, scm_t_bits tag, void *data, void *data2, void *data3) +Make @var{value} contain a smob instance of the type with tag +@var{tag} and smob data @var{data}, @var{data2}, and @var{data3}, as +appropriate. + +The @var{tag} is what has been returned by @code{scm_make_smob_type}. +The initial values @var{data}, @var{data2}, and @var{data3} are of +type @code{scm_t_bits}; when you want to use them for @code{SCM} +values, these values need to be converted to a @code{scm_t_bits} first +by using @code{SCM_UNPACK}. + +The flags of the smob instance start out as zero. +@end deftypefn + +Since it is often the case (e.g., in smob constructors) that you will +create a smob instance and return it, there is also a slightly specialized +macro for this situation: + +@deftypefn {C Macro} {} SCM_RETURN_NEWSMOB (scm_t_bits tag, void *data) +@deftypefnx {C Macro} {} SCM_RETURN_NEWSMOB2 (scm_t_bits tag, void *data1, void *data2) +@deftypefnx {C Macro} {} SCM_RETURN_NEWSMOB3 (scm_t_bits tag, void *data1, void *data2, void *data3) +This macro expands to a block of code that creates a smob instance of +the type with tag @var{tag} and smob data @var{data}, @var{data2}, and +@var{data3}, as with @code{SCM_NEWSMOB}, etc., and causes the +surrounding function to return that @code{SCM} value. It should be +the last piece of code in a block. +@end deftypefn + +@deftypefn {C Macro} scm_t_bits SCM_SMOB_FLAGS (SCM obj) +Return the 16 extra bits of the smob @var{obj}. No meaning is +predefined for these bits, you can use them freely. +@end deftypefn + +@deftypefn {C Macro} scm_t_bits SCM_SET_SMOB_FLAGS (SCM obj, scm_t_bits flags) +Set the 16 extra bits of the smob @var{obj} to @var{flags}. No +meaning is predefined for these bits, you can use them freely. +@end deftypefn + +@deftypefn {C Macro} scm_t_bits SCM_SMOB_DATA (SCM obj) +@deftypefnx {C Macro} scm_t_bits SCM_SMOB_DATA_2 (SCM obj) +@deftypefnx {C Macro} scm_t_bits SCM_SMOB_DATA_3 (SCM obj) +Return the first (second, third) immediate word of the smob @var{obj} +as a @code{scm_t_bits} value. When the word contains a @code{SCM} +value, use @code{SCM_SMOB_OBJECT} (etc.) instead. +@end deftypefn + +@deftypefn {C Macro} void SCM_SET_SMOB_DATA (SCM obj, scm_t_bits val) +@deftypefnx {C Macro} void SCM_SET_SMOB_DATA_2 (SCM obj, scm_t_bits val) +@deftypefnx {C Macro} void SCM_SET_SMOB_DATA_3 (SCM obj, scm_t_bits val) +Set the first (second, third) immediate word of the smob @var{obj} to +@var{val}. When the word should be set to a @code{SCM} value, use +@code{SCM_SMOB_SET_OBJECT} (etc.) instead. +@end deftypefn + +@deftypefn {C Macro} SCM SCM_SMOB_OBJECT (SCM obj) +@deftypefnx {C Macro} SCM SCM_SMOB_OBJECT_2 (SCM obj) +@deftypefnx {C Macro} SCM SCM_SMOB_OBJECT_3 (SCM obj) +Return the first (second, third) immediate word of the smob @var{obj} +as a @code{SCM} value. When the word contains a @code{scm_t_bits} +value, use @code{SCM_SMOB_DATA} (etc.) instead. +@end deftypefn + +@deftypefn {C Macro} void SCM_SET_SMOB_OBJECT (SCM obj, SCM val) +@deftypefnx {C Macro} void SCM_SET_SMOB_OBJECT_2 (SCM obj, SCM val) +@deftypefnx {C Macro} void SCM_SET_SMOB_OBJECT_3 (SCM obj, SCM val) +Set the first (second, third) immediate word of the smob @var{obj} to +@var{val}. When the word should be set to a @code{scm_t_bits} value, use +@code{SCM_SMOB_SET_DATA} (etc.) instead. +@end deftypefn + +@deftypefn {C Macro} {SCM *} SCM_SMOB_OBJECT_LOC (SCM obj) +@deftypefnx {C Macro} {SCM *} SCM_SMOB_OBJECT_2_LOC (SCM obj) +@deftypefnx {C Macro} {SCM *} SCM_SMOB_OBJECT_3_LOC (SCM obj) +Return a pointer to the first (second, third) immediate word of the +smob @var{obj}. Note that this is a pointer to @code{SCM}. If you +need to work with @code{scm_t_bits} values, use @code{SCM_PACK} and +@code{SCM_UNPACK}, as appropriate. +@end deftypefn + +@deftypefun SCM scm_markcdr (SCM @var{x}) +Mark the references in the smob @var{x}, assuming that @var{x}'s first +data word contains an ordinary Scheme object, and @var{x} refers to no +other objects. This function simply returns @var{x}'s first data word. +@end deftypefun + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/api-snarf.texi b/doc/ref/api-snarf.texi new file mode 100644 index 000000000..988f80db6 --- /dev/null +++ b/doc/ref/api-snarf.texi @@ -0,0 +1,143 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + + +@node Snarfing Macros +@section Snarfing Macros +@cindex guile-snarf recognized macros +@cindex guile-snarf deprecated macros + +The following macros do two different things: when compiled normally, +they expand in one way; when processed during snarfing, they cause the +@code{guile-snarf} program to pick up some initialization code, +@xref{Function Snarfing}. + +The descriptions below use the term `normally' to refer to the case +when the code is compiled normally, and `while snarfing' when the code +is processed by @code{guile-snarf}. + +@deffn {C Macro} SCM_SNARF_INIT (code) + +Normally, @code{SCM_SNARF_INIT} expands to nothing; while snarfing, it +causes @var{code} to be included in the initialization action file, +followed by a semicolon. + +This is the fundamental macro for snarfing initialization actions. +The more specialized macros below use it internally. +@end deffn + + +@deffn {C Macro} SCM_DEFINE (c_name, scheme_name, req, opt, var, arglist, docstring) + +Normally, this macro expands into + +@smallexample +static const char s_@var{c_name}[] = @var{scheme_name}; +SCM +@var{c_name} @var{arglist} +@end smallexample + +While snarfing, it causes + +@smallexample +scm_c_define_gsubr (s_@var{c_name}, @var{req}, @var{opt}, @var{var}, + @var{c_name}); +@end smallexample + +to be added to the initialization actions. Thus, you can use it to +declare a C function named @var{c_name} that will be made available to +Scheme with the name @var{scheme_name}. + +Note that the @var{arglist} argument must have parentheses around it. +@end deffn + +@deffn {C Macro} SCM_SYMBOL (c_name, scheme_name) +@deffnx {C Macro} SCM_GLOBAL_SYMBOL (c_name, scheme_name) +Normally, these macros expand into + +@smallexample +static SCM @var{c_name} +@end smallexample + +or + +@smallexample +SCM @var{c_name} +@end smallexample + +respectively. While snarfing, they both expand into the +initialization code + +@smallexample +@var{c_name} = scm_permanent_object (scm_from_symbol (@var{scheme_name})); +@end smallexample + +Thus, you can use them declare a static or global variable of type +@code{SCM} that will be initialized to the symbol named +@var{scheme_name}. +@end deffn + +@deffn {C Macro} SCM_KEYWORD (c_name, scheme_name) +@deffnx {C Macro} SCM_GLOBAL_KEYWORD (c_name, scheme_name) +Normally, these macros expand into + +@smallexample +static SCM @var{c_name} +@end smallexample + +or + +@smallexample +SCM @var{c_name} +@end smallexample + +respectively. While snarfing, they both expand into the +initialization code + +@smallexample +@var{c_name} = scm_permanent_object (scm_from_keyword (@var{scheme_name})); +@end smallexample + +Thus, you can use them declare a static or global variable of type +@code{SCM} that will be initialized to the keyword named +@var{scheme_name}. +@end deffn + +@deffn {C Macro} SCM_VARIABLE (c_name, scheme_name) +@deffnx {C Macro} SCM_GLOBAL_VARIABLE (c_name, scheme_name) +These macros are equivalent to @code{SCM_VARIABLE_INIT} and +@code{SCM_GLOBAL_VARIABLE_INIT}, respectively, with a @var{value} of +@code{SCM_BOOL_F}. +@end deffn + +@deffn {C Macro} SCM_VARIABLE_INIT (c_name, scheme_name, value) +@deffnx {C Macro} SCM_GLOBAL_VARIABLE_INIT (c_name, scheme_name, value) + +Normally, these macros expand into + +@smallexample +static SCM @var{c_name} +@end smallexample + +or + +@smallexample +SCM @var{c_name} +@end smallexample + +respectively. While snarfing, they both expand into the +initialization code + +@smallexample +@var{c_name} = scm_permanent_object (scm_c_define (@var{scheme_name}, @var{value}); +@end smallexample + +Thus, you can use them declare a static or global C variable of type +@code{SCM} that will be initialized to the object representing the +Scheme variable named d@var{scheme_name} in the current module. The +variable will be defined when it doesn't already exist. It is always +set to @var{value}. +@end deffn diff --git a/doc/ref/api-translation.texi b/doc/ref/api-translation.texi new file mode 100644 index 000000000..8782a6fbd --- /dev/null +++ b/doc/ref/api-translation.texi @@ -0,0 +1,54 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Translation +@section Support for Translating Other Languages + +[Describe translation framework.] + +@menu +* Emacs Lisp Support:: Helper primitives for Emacs Lisp. +@end menu + + +@node Emacs Lisp Support +@subsection Emacs Lisp Support + +@deffn {Scheme Procedure} nil-car x +@deffnx {C Function} scm_nil_car (x) +Return the car of @var{x}, but convert it to LISP nil if it +is Scheme's end-of-list. +@end deffn + +@deffn {Scheme Procedure} nil-cdr x +@deffnx {C Function} scm_nil_cdr (x) +Return the cdr of @var{x}, but convert it to LISP nil if it +is Scheme's end-of-list. +@end deffn + +@deffn {Scheme Procedure} nil-cons x y +@deffnx {C Function} scm_nil_cons (x, y) +Create a new cons cell with @var{x} as the car and @var{y} as +the cdr, but convert @var{y} to Scheme's end-of-list if it is +a Lisp nil. +@end deffn + +@deffn {Scheme Procedure} nil-eq x y +Compare @var{x} and @var{y} and return Lisp's t if they are +@code{eq?}, return Lisp's nil otherwise. +@end deffn + +@deffn {Scheme Procedure} null x +@deffnx {C Function} scm_null (x) +Return Lisp's @code{t} if @var{x} is nil in the LISP sense, +return Lisp's nil otherwise. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/api-utility.texi b/doc/ref/api-utility.texi new file mode 100644 index 000000000..8cc662fa7 --- /dev/null +++ b/doc/ref/api-utility.texi @@ -0,0 +1,762 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Utility Functions +@section General Utility Functions + +@c FIXME::martin: Review me! + +This chapter contains information about procedures which are not cleanly +tied to a specific data type. Because of their wide range of +applications, they are collected in a @dfn{utility} chapter. + +@menu +* Equality:: When are two values `the same'? +* Object Properties:: A modern interface to object properties. +* Sorting:: Sort utility procedures. +* Copying:: Copying deep structures. +* General Conversion:: Converting objects to strings. +* Hooks:: User-customizable event lists. +@end menu + + +@node Equality +@subsection Equality + +@c FIXME::martin: Review me! + +@cindex sameness +@cindex equality + +Three different kinds of @dfn{sameness} are defined in Scheme. + +@itemize @bullet +@item +Two values can refer to exactly the same object. + +@item +Two objects can have the same @dfn{value}. + +@item +Two objects can be structurally equivalent. +@end itemize + +The differentiation between these three kinds is important, because +determining whether two values are the same objects is very efficient, +while determining structural equivalence can be quite expensive +(consider comparing two very long lists). Therefore, three different +procedures for testing for equality are provided, which correspond to +the three kinds of @dfn{sameness} defined above. + +@rnindex eq? +@deffn {Scheme Procedure} eq? x y +@deffnx {C Function} scm_eq_p (x, y) +Return @code{#t} iff @var{x} references the same object as @var{y}. +@code{eq?} is similar to @code{eqv?} except that in some cases it is +capable of discerning distinctions finer than those detectable by +@code{eqv?}. +@end deffn + +@deftypefn {C Function} int scm_is_eq (SCM x, SCM y) +Return @code{1} when @var{x} and @var{y} are equal in the sense of +@code{eq?}, else return @code{0}. +@end deftypefn + +@rnindex eqv? +@deffn {Scheme Procedure} eqv? x y +@deffnx {C Function} scm_eqv_p (x, y) +The @code{eqv?} procedure defines a useful equivalence relation on objects. +Briefly, it returns @code{#t} if @var{x} and @var{y} should normally be +regarded as the same object. This relation is left slightly open to +interpretation, but works for comparing immediate integers, characters, +and inexact numbers. +@end deffn + +@rnindex equal? +@deffn {Scheme Procedure} equal? x y +@deffnx {C Function} scm_equal_p (x, y) +Return @code{#t} iff @var{x} and @var{y} are recursively @code{eqv?} +equivalent. @code{equal?} recursively compares the contents of pairs, +vectors, and strings, applying @code{eqv?} on other objects such as +numbers and symbols. A rule of thumb is that objects are generally +@code{equal?} if they print the same. @code{equal?} may fail to +terminate if its arguments are circular data structures. +@end deffn + + +@node Object Properties +@subsection Object Properties + +It's often useful to associate a piece of additional information with a +Scheme object even though that object does not have a dedicated slot +available in which the additional information could be stored. Object +properties allow you to do just that. + +An object property is most commonly used to associate one kind of +additional information with each instance of a class of similar Scheme +objects. For example, all procedures have a `name' property, which +stores the name of the variable in which the procedure was stored by a +@code{define} expression, or @code{#f} if the procedure wasn't created +by that kind of expression. + +Guile's representation of an object property is a procedure-with-setter +(@pxref{Procedures with Setters}) that can be used with the generalized +form of @code{set!} (REFFIXME) to set and retrieve that property for any +Scheme object. So, setting a property looks like this: + +@lisp +(set! (my-property obj1) value-for-obj1) +(set! (my-property obj2) value-for-obj2) +@end lisp + +@noindent +And retrieving values of the same property looks like this: + +@lisp +(my-property obj1) +@result{} +value-for-obj1 + +(my-property obj2) +@result{} +value-for-obj2 +@end lisp + +To create an object property in the first place, use the +@code{make-object-property} procedure: + +@lisp +(define my-property (make-object-property)) +@end lisp + +@deffn {Scheme Procedure} make-object-property +Create and return an object property. An object property is a +procedure-with-setter that can be called in two ways. @code{(set! +(@var{property} @var{obj}) @var{val})} sets @var{obj}'s @var{property} +to @var{val}. @code{(@var{property} @var{obj})} returns the current +setting of @var{obj}'s @var{property}. +@end deffn + +A single object property created by @code{make-object-property} can +associate distinct property values with all Scheme values that are +distinguishable by @code{eq?} (including, for example, integers). + +Internally, object properties are implemented using a weak key hash +table. This means that, as long as a Scheme value with property values +is protected from garbage collection, its property values are also +protected. When the Scheme value is collected, its entry in the +property table is removed and so the (ex-) property values are no longer +protected by the table. + +@menu +* Property Primitives:: Low level property implementation. +* Old-fashioned Properties:: An older approach to properties. +@end menu + + +@node Property Primitives +@subsubsection Low Level Property Implementation. + +@deffn {Scheme Procedure} primitive-make-property not-found-proc +@deffnx {C Function} scm_primitive_make_property (not_found_proc) +Create a @dfn{property token} that can be used with +@code{primitive-property-ref} and @code{primitive-property-set!}. +See @code{primitive-property-ref} for the significance of +@var{not-found-proc}. +@end deffn + +@deffn {Scheme Procedure} primitive-property-ref prop obj +@deffnx {C Function} scm_primitive_property_ref (prop, obj) +Return the property @var{prop} of @var{obj}. + +When no value has yet been associated with @var{prop} and @var{obj}, +the @var{not-found-proc} from @var{prop} is used. A call +@code{(@var{not-found-proc} @var{prop} @var{obj})} is made and the +result set as the property value. If @var{not-found-proc} is +@code{#f} then @code{#f} is the property value. +@end deffn + +@deffn {Scheme Procedure} primitive-property-set! prop obj val +@deffnx {C Function} scm_primitive_property_set_x (prop, obj, val) +Set the property @var{prop} of @var{obj} to @var{val}. +@end deffn + +@deffn {Scheme Procedure} primitive-property-del! prop obj +@deffnx {C Function} scm_primitive_property_del_x (prop, obj) +Remove any value associated with @var{prop} and @var{obj}. +@end deffn + + +@node Old-fashioned Properties +@subsubsection An Older Approach to Properties + +Traditionally, Lisp systems provide a different object property +interface to that provided by @code{make-object-property}, in which the +object property that is being set or retrieved is indicated by a symbol. + +Guile includes this older kind of interface as well, but it may well be +removed in a future release, as it is less powerful than +@code{make-object-property} and so increases the size of the Guile +library for no benefit. (And it is trivial to write a compatibility +layer in Scheme.) + +@deffn {Scheme Procedure} object-properties obj +@deffnx {C Function} scm_object_properties (obj) +Return @var{obj}'s property list. +@end deffn + +@deffn {Scheme Procedure} set-object-properties! obj alist +@deffnx {C Function} scm_set_object_properties_x (obj, alist) +Set @var{obj}'s property list to @var{alist}. +@end deffn + +@deffn {Scheme Procedure} object-property obj key +@deffnx {C Function} scm_object_property (obj, key) +Return the property of @var{obj} with name @var{key}. +@end deffn + +@deffn {Scheme Procedure} set-object-property! obj key value +@deffnx {C Function} scm_set_object_property_x (obj, key, value) +In @var{obj}'s property list, set the property named @var{key} +to @var{value}. +@end deffn + + +@node Sorting +@subsection Sorting + +@c FIXME::martin: Review me! + +@cindex sorting +@cindex sorting lists +@cindex sorting vectors + +Sorting is very important in computer programs. Therefore, Guile comes +with several sorting procedures built-in. As always, procedures with +names ending in @code{!} are side-effecting, that means that they may +modify their parameters in order to produce their results. + +The first group of procedures can be used to merge two lists (which must +be already sorted on their own) and produce sorted lists containing +all elements of the input lists. + +@deffn {Scheme Procedure} merge alist blist less +@deffnx {C Function} scm_merge (alist, blist, less) +Merge two already sorted lists into one. +Given two lists @var{alist} and @var{blist}, such that +@code{(sorted? alist less?)} and @code{(sorted? blist less?)}, +return a new list in which the elements of @var{alist} and +@var{blist} have been stably interleaved so that +@code{(sorted? (merge alist blist less?) less?)}. +Note: this does _not_ accept vectors. +@end deffn + +@deffn {Scheme Procedure} merge! alist blist less +@deffnx {C Function} scm_merge_x (alist, blist, less) +Takes two lists @var{alist} and @var{blist} such that +@code{(sorted? alist less?)} and @code{(sorted? blist less?)} and +returns a new list in which the elements of @var{alist} and +@var{blist} have been stably interleaved so that + @code{(sorted? (merge alist blist less?) less?)}. +This is the destructive variant of @code{merge} +Note: this does _not_ accept vectors. +@end deffn + +The following procedures can operate on sequences which are either +vectors or list. According to the given arguments, they return sorted +vectors or lists, respectively. The first of the following procedures +determines whether a sequence is already sorted, the other sort a given +sequence. The variants with names starting with @code{stable-} are +special in that they maintain a special property of the input sequences: +If two or more elements are the same according to the comparison +predicate, they are left in the same order as they appeared in the +input. + +@deffn {Scheme Procedure} sorted? items less +@deffnx {C Function} scm_sorted_p (items, less) +Return @code{#t} iff @var{items} is a list or a vector such that +for all 1 <= i <= m, the predicate @var{less} returns true when +applied to all elements i - 1 and i +@end deffn + +@deffn {Scheme Procedure} sort items less +@deffnx {C Function} scm_sort (items, less) +Sort the sequence @var{items}, which may be a list or a +vector. @var{less} is used for comparing the sequence +elements. This is not a stable sort. +@end deffn + +@deffn {Scheme Procedure} sort! items less +@deffnx {C Function} scm_sort_x (items, less) +Sort the sequence @var{items}, which may be a list or a +vector. @var{less} is used for comparing the sequence +elements. The sorting is destructive, that means that the +input sequence is modified to produce the sorted result. +This is not a stable sort. +@end deffn + +@deffn {Scheme Procedure} stable-sort items less +@deffnx {C Function} scm_stable_sort (items, less) +Sort the sequence @var{items}, which may be a list or a +vector. @var{less} is used for comparing the sequence elements. +This is a stable sort. +@end deffn + +@deffn {Scheme Procedure} stable-sort! items less +@deffnx {C Function} scm_stable_sort_x (items, less) +Sort the sequence @var{items}, which may be a list or a +vector. @var{less} is used for comparing the sequence elements. +The sorting is destructive, that means that the input sequence +is modified to produce the sorted result. +This is a stable sort. +@end deffn + +The procedures in the last group only accept lists or vectors as input, +as their names indicate. + +@deffn {Scheme Procedure} sort-list items less +@deffnx {C Function} scm_sort_list (items, less) +Sort the list @var{items}, using @var{less} for comparing the +list elements. This is a stable sort. +@end deffn + +@deffn {Scheme Procedure} sort-list! items less +@deffnx {C Function} scm_sort_list_x (items, less) +Sort the list @var{items}, using @var{less} for comparing the +list elements. The sorting is destructive, that means that the +input list is modified to produce the sorted result. +This is a stable sort. +@end deffn + +@deffn {Scheme Procedure} restricted-vector-sort! vec less startpos endpos +@deffnx {C Function} scm_restricted_vector_sort_x (vec, less, startpos, endpos) +Sort the vector @var{vec}, using @var{less} for comparing +the vector elements. @var{startpos} and @var{endpos} delimit +the range of the vector which gets sorted. The return value +is not specified. +@end deffn + + +@node Copying +@subsection Copying Deep Structures + +@c FIXME::martin: Review me! + +The procedures for copying lists (@pxref{Lists}) only produce a flat +copy of the input list, and currently Guile does not even contain +procedures for copying vectors. @code{copy-tree} can be used for these +application, as it does not only copy the spine of a list, but also +copies any pairs in the cars of the input lists. + +@deffn {Scheme Procedure} copy-tree obj +@deffnx {C Function} scm_copy_tree (obj) +Recursively copy the data tree that is bound to @var{obj}, and return a +pointer to the new data structure. @code{copy-tree} recurses down the +contents of both pairs and vectors (since both cons cells and vector +cells may point to arbitrary objects), and stops recursing when it hits +any other object. +@end deffn + + +@node General Conversion +@subsection General String Conversion + +@c FIXME::martin: Review me! + +When debugging Scheme programs, but also for providing a human-friendly +interface, a procedure for converting any Scheme object into string +format is very useful. Conversion from/to strings can of course be done +with specialized procedures when the data type of the object to convert +is known, but with this procedure, it is often more comfortable. + +@code{object->string} converts an object by using a print procedure for +writing to a string port, and then returning the resulting string. +Converting an object back from the string is only possible if the object +type has a read syntax and the read syntax is preserved by the printing +procedure. + +@deffn {Scheme Procedure} object->string obj [printer] +@deffnx {C Function} scm_object_to_string (obj, printer) +Return a Scheme string obtained by printing @var{obj}. +Printing function can be specified by the optional second +argument @var{printer} (default: @code{write}). +@end deffn + + +@node Hooks +@subsection Hooks +@tpindex Hooks + +A hook is a list of procedures to be called at well defined points in +time. Typically, an application provides a hook @var{h} and promises +its users that it will call all of the procedures in @var{h} at a +defined point in the application's processing. By adding its own +procedure to @var{h}, an application user can tap into or even influence +the progress of the application. + +Guile itself provides several such hooks for debugging and customization +purposes: these are listed in a subsection below. + +When an application first creates a hook, it needs to know how many +arguments will be passed to the hook's procedures when the hook is run. +The chosen number of arguments (which may be none) is declared when the +hook is created, and all the procedures that are added to that hook must +be capable of accepting that number of arguments. + +A hook is created using @code{make-hook}. A procedure can be added to +or removed from a hook using @code{add-hook!} or @code{remove-hook!}, +and all of a hook's procedures can be removed together using +@code{reset-hook!}. When an application wants to run a hook, it does so +using @code{run-hook}. + +@menu +* Hook Example:: Hook usage by example. +* Hook Reference:: Reference of all hook procedures. +* C Hooks:: Hooks for use from C code. +* GC Hooks:: Garbage collection hooks. +* REPL Hooks:: Hooks into the Guile REPL. +@end menu + + +@node Hook Example +@subsubsection Hook Usage by Example + +Hook usage is shown by some examples in this section. First, we will +define a hook of arity 2 --- that is, the procedures stored in the hook +will have to accept two arguments. + +@lisp +(define hook (make-hook 2)) +hook +@result{} #<hook 2 40286c90> +@end lisp + +Now we are ready to add some procedures to the newly created hook with +@code{add-hook!}. In the following example, two procedures are added, +which print different messages and do different things with their +arguments. + +@lisp +(add-hook! hook (lambda (x y) + (display "Foo: ") + (display (+ x y)) + (newline))) +(add-hook! hook (lambda (x y) + (display "Bar: ") + (display (* x y)) + (newline))) +@end lisp + +Once the procedures have been added, we can invoke the hook using +@code{run-hook}. + +@lisp +(run-hook hook 3 4) +@print{} Bar: 12 +@print{} Foo: 7 +@end lisp + +Note that the procedures are called in the reverse of the order with +which they were added. This is because the default behaviour of +@code{add-hook!} is to add its procedure to the @emph{front} of the +hook's procedure list. You can force @code{add-hook!} to add its +procedure to the @emph{end} of the list instead by providing a third +@code{#t} argument on the second call to @code{add-hook!}. + +@lisp +(add-hook! hook (lambda (x y) + (display "Foo: ") + (display (+ x y)) + (newline))) +(add-hook! hook (lambda (x y) + (display "Bar: ") + (display (* x y)) + (newline)) + #t) ; @r{<- Change here!} + +(run-hook hook 3 4) +@print{} Foo: 7 +@print{} Bar: 12 +@end lisp + + +@node Hook Reference +@subsubsection Hook Reference + +When you create a hook with @code{make-hook}, you must specify the arity +of the procedures which can be added to the hook. If the arity is not +given explicitly as an argument to @code{make-hook}, it defaults to +zero. All procedures of a given hook must have the same arity, and when +the procedures are invoked using @code{run-hook}, the number of +arguments passed must match the arity specified at hook creation time. + +The order in which procedures are added to a hook matters. If the third +parameter to @code{add-hook!} is omitted or is equal to @code{#f}, the +procedure is added in front of the procedures which might already be on +that hook, otherwise the procedure is added at the end. The procedures +are always called from the front to the end of the list when they are +invoked via @code{run-hook}. + +The ordering of the list of procedures returned by @code{hook->list} +matches the order in which those procedures would be called if the hook +was run using @code{run-hook}. + +Note that the C functions in the following entries are for handling +@dfn{Scheme-level} hooks in C. There are also @dfn{C-level} hooks which +have their own interface (@pxref{C Hooks}). + +@deffn {Scheme Procedure} make-hook [n_args] +@deffnx {C Function} scm_make_hook (n_args) +Create a hook for storing procedure of arity @var{n_args}. +@var{n_args} defaults to zero. The returned value is a hook +object to be used with the other hook procedures. +@end deffn + +@deffn {Scheme Procedure} hook? x +@deffnx {C Function} scm_hook_p (x) +Return @code{#t} if @var{x} is a hook, @code{#f} otherwise. +@end deffn + +@deffn {Scheme Procedure} hook-empty? hook +@deffnx {C Function} scm_hook_empty_p (hook) +Return @code{#t} if @var{hook} is an empty hook, @code{#f} +otherwise. +@end deffn + +@deffn {Scheme Procedure} add-hook! hook proc [append_p] +@deffnx {C Function} scm_add_hook_x (hook, proc, append_p) +Add the procedure @var{proc} to the hook @var{hook}. The +procedure is added to the end if @var{append_p} is true, +otherwise it is added to the front. The return value of this +procedure is not specified. +@end deffn + +@deffn {Scheme Procedure} remove-hook! hook proc +@deffnx {C Function} scm_remove_hook_x (hook, proc) +Remove the procedure @var{proc} from the hook @var{hook}. The +return value of this procedure is not specified. +@end deffn + +@deffn {Scheme Procedure} reset-hook! hook +@deffnx {C Function} scm_reset_hook_x (hook) +Remove all procedures from the hook @var{hook}. The return +value of this procedure is not specified. +@end deffn + +@deffn {Scheme Procedure} hook->list hook +@deffnx {C Function} scm_hook_to_list (hook) +Convert the procedure list of @var{hook} to a list. +@end deffn + +@deffn {Scheme Procedure} run-hook hook . args +@deffnx {C Function} scm_run_hook (hook, args) +Apply all procedures from the hook @var{hook} to the arguments +@var{args}. The order of the procedure application is first to +last. The return value of this procedure is not specified. +@end deffn + +If, in C code, you are certain that you have a hook object and well +formed argument list for that hook, you can also use +@code{scm_c_run_hook}, which is identical to @code{scm_run_hook} but +does no type checking. + +@deftypefn {C Function} void scm_c_run_hook (SCM hook, SCM args) +The same as @code{scm_run_hook} but without any type checking to confirm +that @var{hook} is actually a hook object and that @var{args} is a +well-formed list matching the arity of the hook. +@end deftypefn + +For C code, @code{SCM_HOOKP} is a faster alternative to +@code{scm_hook_p}: + +@deftypefn {C Macro} int SCM_HOOKP (x) +Return 1 if @var{x} is a Scheme-level hook, 0 otherwise. +@end deftypefn + + +@subsubsection Handling Scheme-level hooks from C code + +Here is an example of how to handle Scheme-level hooks from C code using +the above functions. + +@example +if (scm_is_true (scm_hook_p (obj))) + /* handle Scheme-level hook using C functions */ + scm_reset_hook_x (obj); +else + /* do something else (obj is not a hook) */ +@end example + + +@node C Hooks +@subsubsection Hooks For C Code. + +The hooks already described are intended to be populated by Scheme-level +procedures. In addition to this, the Guile library provides an +independent set of interfaces for the creation and manipulation of hooks +that are designed to be populated by functions implemented in C. + +The original motivation here was to provide a kind of hook that could +safely be invoked at various points during garbage collection. +Scheme-level hooks are unsuitable for this purpose as running them could +itself require memory allocation, which would then invoke garbage +collection recursively @dots{} However, it is also the case that these +hooks are easier to work with than the Scheme-level ones if you only +want to register C functions with them. So if that is mainly what your +code needs to do, you may prefer to use this interface. + +To create a C hook, you should allocate storage for a structure of type +@code{scm_t_c_hook} and then initialize it using @code{scm_c_hook_init}. + +@deftp {C Type} scm_t_c_hook +Data type for a C hook. The internals of this type should be treated as +opaque. +@end deftp + +@deftp {C Enum} scm_t_c_hook_type +Enumeration of possible hook types, which are: + +@table @code +@item SCM_C_HOOK_NORMAL +@vindex SCM_C_HOOK_NORMAL +Type of hook for which all the registered functions will always be called. +@item SCM_C_HOOK_OR +@vindex SCM_C_HOOK_OR +Type of hook for which the sequence of registered functions will be +called only until one of them returns C true (a non-NULL pointer). +@item SCM_C_HOOK_AND +@vindex SCM_C_HOOK_AND +Type of hook for which the sequence of registered functions will be +called only until one of them returns C false (a NULL pointer). +@end table +@end deftp + +@deftypefn {C Function} void scm_c_hook_init (scm_t_c_hook *hook, void *hook_data, scm_t_c_hook_type type) +Initialize the C hook at memory pointed to by @var{hook}. @var{type} +should be one of the values of the @code{scm_t_c_hook_type} enumeration, +and controls how the hook functions will be called. @var{hook_data} is +a closure parameter that will be passed to all registered hook functions +when they are called. +@end deftypefn + +To add or remove a C function from a C hook, use @code{scm_c_hook_add} +or @code{scm_c_hook_remove}. A hook function must expect three +@code{void *} parameters which are, respectively: + +@table @var +@item hook_data +The hook closure data that was specified at the time the hook was +initialized by @code{scm_c_hook_init}. + +@item func_data +The function closure data that was specified at the time that that +function was registered with the hook by @code{scm_c_hook_add}. + +@item data +The call closure data specified by the @code{scm_c_hook_run} call that +runs the hook. +@end table + +@deftp {C Type} scm_t_c_hook_function +Function type for a C hook function: takes three @code{void *} +parameters and returns a @code{void *} result. +@end deftp + +@deftypefn {C Function} void scm_c_hook_add (scm_t_c_hook *hook, scm_t_c_hook_function func, void *func_data, int appendp) +Add function @var{func}, with function closure data @var{func_data}, to +the C hook @var{hook}. The new function is appended to the hook's list +of functions if @var{appendp} is non-zero, otherwise prepended. +@end deftypefn + +@deftypefn {C Function} void scm_c_hook_remove (scm_t_c_hook *hook, scm_t_c_hook_function func, void *func_data) +Remove function @var{func}, with function closure data @var{func_data}, +from the C hook @var{hook}. @code{scm_c_hook_remove} checks both +@var{func} and @var{func_data} so as to allow for the same @var{func} +being registered multiple times with different closure data. +@end deftypefn + +Finally, to invoke a C hook, call the @code{scm_c_hook_run} function +specifying the hook and the call closure data for this run: + +@deftypefn {C Function} {void *} scm_c_hook_run (scm_t_c_hook *hook, void *data) +Run the C hook @var{hook} will call closure data @var{data}. Subject to +the variations for hook types @code{SCM_C_HOOK_OR} and +@code{SCM_C_HOOK_AND}, @code{scm_c_hook_run} calls @var{hook}'s +registered functions in turn, passing them the hook's closure data, each +function's closure data, and the call closure data. + +@code{scm_c_hook_run}'s return value is the return value of the last +function to be called. +@end deftypefn + + +@node GC Hooks +@subsubsection Hooks for Garbage Collection + +Whenever Guile performs a garbage collection, it calls the following +hooks in the order shown. + +@defvr {C Hook} scm_before_gc_c_hook +C hook called at the very start of a garbage collection, after setting +@code{scm_gc_running_p} to 1, but before entering the GC critical +section. + +If garbage collection is blocked because @code{scm_block_gc} is +non-zero, GC exits early soon after calling this hook, and no further +hooks will be called. +@end defvr + +@defvr {C Hook} scm_before_mark_c_hook +C hook called before beginning the mark phase of garbage collection, +after the GC thread has entered a critical section. +@end defvr + +@defvr {C Hook} scm_before_sweep_c_hook +C hook called before beginning the sweep phase of garbage collection. +This is the same as at the end of the mark phase, since nothing else +happens between marking and sweeping. +@end defvr + +@defvr {C Hook} scm_after_sweep_c_hook +C hook called after the end of the sweep phase of garbage collection, +but while the GC thread is still inside its critical section. +@end defvr + +@defvr {C Hook} scm_after_gc_c_hook +C hook called at the very end of a garbage collection, after the GC +thread has left its critical section. +@end defvr + +@defvr {Scheme Hook} after-gc-hook +@vindex scm_after_gc_hook +Scheme hook with arity 0. This hook is run asynchronously +(@pxref{Asyncs}) soon after the GC has completed and any other events +that were deferred during garbage collection have been processed. (Also +accessible from C with the name @code{scm_after_gc_hook}.) +@end defvr + +All the C hooks listed here have type @code{SCM_C_HOOK_NORMAL}, are +initialized with hook closure data NULL, are are invoked by +@code{scm_c_hook_run} with call closure data NULL. + +@cindex guardians, testing for GC'd objects +The Scheme hook @code{after-gc-hook} is particularly useful in +conjunction with guardians (@pxref{Guardians}). Typically, if you are +using a guardian, you want to call the guardian after garbage collection +to see if any of the objects added to the guardian have been collected. +By adding a thunk that performs this call to @code{after-gc-hook}, you +can ensure that your guardian is tested after every garbage collection +cycle. + + +@node REPL Hooks +@subsubsection Hooks into the Guile REPL + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/deprecated.texi b/doc/ref/deprecated.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/deprecated.texi +++ /dev/null diff --git a/doc/ref/guile.texi b/doc/ref/guile.texi index 9965e977e..134ba7c29 100644 --- a/doc/ref/guile.texi +++ b/doc/ref/guile.texi @@ -137,7 +137,7 @@ x @comment The title is printed in a large font. @title Guile Reference Manual @subtitle Edition @value{MANUAL-EDITION}, for use with Guile @value{VERSION} -@c @subtitle $Id: guile.texi,v 1.34 2004-08-02 11:46:57 mvo Exp $ +@c @subtitle $Id: guile.texi,v 1.35 2004-08-02 12:29:00 mvo Exp $ @c See preface.texi for the list of authors @author The Guile Developers @@ -225,8 +225,8 @@ etc. that make up Guile's application programming interface (API), @include scheme-ideas.texi @include scheme-intro.texi -@include scripts.texi -@include debugging.texi +@include scheme-scripts.texi +@include scheme-debugging.texi @include scheme-reading.texi @node Programming in C @@ -306,27 +306,27 @@ available through both Scheme and C interfaces. * GH:: The deprecated GH interface. @end menu -@include scm.texi -@include scheme-scm.texi -@include ref-init.texi -@include scheme-snarf.texi -@include scheme-data.texi -@include scheme-compound.texi -@include scheme-smobs.texi -@include scheme-procedures.texi -@include scheme-utility.texi -@include scheme-binding.texi -@include scheme-control.texi -@include scheme-io.texi -@include scheme-evaluation.texi -@include scheme-memory.texi -@include scheme-modules.texi -@include scheme-scheduling.texi +@include api-overview.texi +@include api-scm.texi +@include api-init.texi +@include api-snarf.texi +@include api-data.texi +@include api-compound.texi +@include api-smobs.texi +@include api-procedures.texi +@include api-utility.texi +@include api-binding.texi +@include api-control.texi +@include api-io.texi +@include api-evaluation.texi +@include api-memory.texi +@include api-modules.texi +@include api-scheduling.texi @c object orientation support here -@include scheme-options.texi -@include scheme-translation.texi -@include scheme-debug.texi -@include deprecated.texi +@include api-options.texi +@include api-translation.texi +@include api-debug.texi +@include api-deprecated.texi @include gh.texi @node Guile Modules diff --git a/doc/ref/ref-init.texi b/doc/ref/ref-init.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/ref-init.texi +++ /dev/null diff --git a/doc/ref/scheme-binding.texi b/doc/ref/scheme-binding.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-binding.texi +++ /dev/null diff --git a/doc/ref/scheme-compound.texi b/doc/ref/scheme-compound.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-compound.texi +++ /dev/null diff --git a/doc/ref/scheme-control.texi b/doc/ref/scheme-control.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-control.texi +++ /dev/null diff --git a/doc/ref/scheme-data.texi b/doc/ref/scheme-data.texi deleted file mode 100755 index e69de29bb..000000000 --- a/doc/ref/scheme-data.texi +++ /dev/null diff --git a/doc/ref/scheme-debug.texi b/doc/ref/scheme-debug.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-debug.texi +++ /dev/null diff --git a/doc/ref/scheme-debugging.texi b/doc/ref/scheme-debugging.texi new file mode 100644 index 000000000..6168ac886 --- /dev/null +++ b/doc/ref/scheme-debugging.texi @@ -0,0 +1,1045 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Debugging Features +@section Debugging Features + +Guile includes debugging tools to help you work out what is going wrong +when a program signals an error or behaves differently to how you would +expect. This chapter describes how to use these tools. + +Broadly speaking, Guile's debugging support allows you to do two things: + +@itemize @bullet +@item +specify @dfn{breakpoints} --- points in the execution of a program where +execution should pause so you can see what is going on + +@item +examine in detail the ``scene of the crime'' --- in other words, the +execution context at a breakpoint, or when the last error occurred. +@end itemize + +@noindent +The details are more complex and more powerful @dots{} + +@menu +* Debug Last Error:: Debugging the most recent error. +* Intro to Breakpoints:: Setting and manipulating them. +* Interactive Debugger:: Using the interactive debugger. +* Tracing:: Tracing program execution. +@end menu + + +@node Debug Last Error +@subsection Debugging the Most Recent Error + +When an error is signalled, Guile remembers the execution context where +the error occurred. By default, Guile then displays only the most +immediate information about where and why the error occurred, for +example: + +@lisp +(make-string (* 4 (+ 3 #\s)) #\space) +@print{} +standard input:2:19: In procedure + in expression (+ 3 #\s): +standard input:2:19: Wrong type argument: #\s +ABORT: (wrong-type-arg) + +Type "(backtrace)" to get more information or "(debug)" to enter the debugger. +@end lisp + +@noindent +However, as the message above says, you can obtain much more +information about the context of the error by typing +@code{(backtrace)} or @code{(debug)}. + +@code{(backtrace)} displays the Scheme call stack at the point where the +error occurred: + +@lisp +(backtrace) +@print{} +Backtrace: +In standard input: + 2: 0* [make-string ... + 2: 1* [* 4 ... + 2: 2* [+ 3 #\s] + +Type "(debug-enable 'backtrace)" if you would like a backtrace +automatically if an error occurs in the future. +@end lisp + +@noindent +In a more complex scenario than this one, this can be extremely useful +for understanding where and why the error occurred. For more on the +format of the displayed backtrace, see the subsection below. + +@code{(debug)} takes you into Guile's interactive debugger, which +provides commands that allow you to + +@itemize @bullet +@item +display the Scheme call stack at the point where the error occurred +(the @code{backtrace} command --- see @ref{Display Backtrace}) + +@item +move up and down the call stack, to see in detail the expression being +evaluated, or the procedure being applied, in each @dfn{frame} (the +@code{up}, @code{down}, @code{frame}, @code{position}, @code{info args} +and @code{info frame} commands --- see @ref{Frame Selection} and +@ref{Frame Information}) + +@item +examine the values of variables and expressions in the context of each +frame (the @code{evaluate} command --- see @ref{Frame Evaluation}). +@end itemize + +Use of the interactive debugger, including these commands, is described +in @ref{Interactive Debugger}. + +@menu +* Backtrace Format:: How to interpret a backtrace. +@end menu + + +@node Backtrace Format +@subsubsection How to Interpret a Backtrace + + +@node Intro to Breakpoints +@subsection Intro to Breakpoints + +If you are not already familiar with the concept of breakpoints, the +first subsection below explains how they work are why they are useful. + +Broadly speaking, Guile's breakpoint support consists of + +@itemize @bullet +@item +type-specific features for @emph{creating} breakpoints of various types + +@item +relatively generic features for @emph{manipulating} the behaviour of +breakpoints once they've been created. +@end itemize + +Different breakpoint types are implemented as different classes in a +GOOPS hierarchy with common base class @code{<breakpoint>}. The magic +of generic functions then allows most of the manipulation functions to +be generic by default but specializable (by breakpoint class) if the +need arises. + +Generic breakpoint support is provided by the @code{(ice-9 debugger +breakpoints)} module, so you will almost always need to use this module +in order to access the functionality described here: + +@smalllisp +(use-modules (ice-9 debugger breakpoints)) +@end smalllisp + +@noindent +You may like to add this to your @file{.guile} file. + +@menu +* Breakpoints Overview:: +* Source Breakpoints:: +* Procedural Breakpoints:: +* Setting Breakpoints:: +* break! trace! trace-subtree!:: +* Accessing Breakpoints:: +* Breakpoint Behaviours:: +* Enabling and Disabling:: +* Deleting Breakpoints:: +* Breakpoint Information:: +* Other Breakpoint Types:: +@end menu + + +@node Breakpoints Overview +@subsubsection How Breakpoints Work and Why They Are Useful + +Often, debugging the last error is not enough to tell you what went +wrong. For example, the root cause of the error may have arisen a long +time before the error was signalled, in which case the execution context +of the error is too late to be useful. Or your program might not signal +an error at all, just return an unexpected result or have some incorrect +side effect. + +In many such cases, it's useful to pause the program at or before the +point where you suspect the problem arises. Then you can explore the +stack, display the values of key variables, and generally check that the +state of the program is as you expect. If all is well, you can let the +program continue running normally, or step more slowly through each +expression that the Scheme interpreter evaluates. Single-stepping may +reveal that the program is going through blocks of code that you didn't +intend --- a useful data point for understanding what the underlying +problem is. + +Telling Guile where or when to pause a program is called @dfn{setting a +breakpoint}. When a breakpoint is hit, Guile's default behaviour is to +enter the interactive debugger, where there are now two sets of commands +available: + +@itemize @bullet +@item +all the commands as described for last error debugging (@pxref{Debug +Last Error}), which allow you to explore the stack and so on + +@item +additional commands for continuing program execution in various ways: +@code{next}, @code{step}, @code{finish}, @code{trace-finish} and +@code{continue}. +@end itemize + +Use of the interactive debugger is described in @ref{Interactive +Debugger}. + + +@node Source Breakpoints +@subsubsection Source Breakpoints + +A source breakpoint is a breakpoint that triggers whenever program +execution hits a particular source location. A source breakpoint can be +conveniently set simply by evaluating code that has @code{##} inserted +into it at the position where you want the breakpoint to be. + +For example, to set a breakpoint immediately before evaluation of +@code{(= n 0)} in the following procedure definition, evaluate: + +@smalllisp +(define (fact1 n) + (if ##(= n 0) + 1 + (* n (fact1 (- n 1))))) +@print{} +Set breakpoint 1: standard input:4:9: (= n 0) +@end smalllisp + +@noindent +Note the message confirming that you have set a breakpoint. If you +don't see this, something isn't working. + +@code{##} is provided by the @code{(ice-9 debugger breakpoints source)} module, +so you must use this module before trying to set breakpoints in this +way: + +@smalllisp +(use-modules (ice-9 debugger breakpoints source)) +@end smalllisp + +@noindent +You may like to add this to your @file{.guile} file. + +The default behaviour for source breakpoints is @code{debug-here} +(@pxref{Breakpoint Behaviours}), which means to enter the command line +debugger when the breakpoint is hit. So, if you now use @code{fact1}, +that is what happens. + +@smalllisp +guile> (fact1 3) +Hit breakpoint 1: standard input:4:9: (= n 0) +Frame 3 at standard input:4:9 + (= n 0) +debug> +@end smalllisp + + +@node Procedural Breakpoints +@subsubsection Procedural Breakpoints + +A procedural breakpoint is a breakpoint that triggers whenever Guile is +about to apply a specified procedure to its (already evaluated) +arguments. To set a procedural breakpoint, call @code{break!} with the +target procedure as a single argument. For example: + +@smalllisp +(define (fact1 n) + (if (= n 0) + 1 + (* n (fact1 (- n 1))))) + +(break! fact1) +@print{} +Set breakpoint 1: [fact1] +@result{} +#<<procedure-breakpoint> 808b0b0> +@end smalllisp + +Alternatives to @code{break!} are @code{trace!} and +@code{trace-subtree!}. The difference is that these three calls create +a breakpoint in the same place but with three different behaviours, +respectively @code{debug-here}, @code{trace-here} and +@code{trace-subtree}. Breakpoint behaviours are documented fully later +(@pxref{Breakpoint Behaviours}), but to give a quick taste, here's an +example of running code that includes a procedural breakpoint with the +@code{trace-here} behaviour. + +@smalllisp +(trace! fact1) +@print{} +Set breakpoint 1: [fact1] +@result{} +#<<procedure-breakpoint> 808b0b0> + +(fact1 4) +@print{} +| [fact1 4] +| | [fact1 3] +| | | [fact1 2] +| | | | [fact1 1] +| | | | | [fact1 0] +| | | | | 1 +| | | | 2 +| | | 6 +| | 24 +| 24 +@result{} +24 +@end smalllisp + +To set and use procedural breakpoints, you will need to use the +@code{(ice-9 debugger breakpoints procedural)} module: + +@smalllisp +(use-modules (ice-9 debugger breakpoints procedural)) +@end smalllisp + +@noindent +You may like to add this to your @file{.guile} file. + + +@node Setting Breakpoints +@subsubsection Setting Breakpoints + +In general, that is. We've already seen how to set source and +procedural breakpoints conveniently in practice. This section explains +how those conveniences map onto a more general mechanism. + +The general mechanism for setting breakpoints is the generic function +@code{set-breakpoint!}. Different kinds of breakpoints define +subclasses of the class @code{<breakpoint>} and provide their own +methods for @code{set-pbreakpoint!}. + +For example, @code{(ice-9 debugger breakpoints procedural)} implements +the @code{<procedure-breakpoint>} subclass and provides a +@code{set-breakpoint!} method that takes a procedure argument: + +@smalllisp +(set-breakpoint! @var{behavior} fact1) +@print{} +Set breakpoint 1: [fact1] +@result{} +#<<procedure-breakpoint> 808b0b0> +@end smalllisp + +A non-type-specific @code{set-breakpoint!} method is provided by the +generic module @code{(ice-9 debugger breakpoints)}. It allows you to +change the behaviour of an existing breakpoint that is identified by +its breakpoint number. + +@smalllisp +(set-breakpoint! @var{behavior} 1) +@end smalllisp + +@node break! trace! trace-subtree! +@subsubsection break! trace! trace-subtree! + +We have already talked above about the use of @code{break!}, +@code{trace!} and @code{trace-subtree!} for setting procedural +breakpoints. Now that @code{set-breakpoint!} has been introduced, we +can reveal that @code{break!}, @code{trace!} and @code{trace-subtree!} +are in fact just wrappers for @code{set-breakpoint!} that specify +particular breakpoint behaviours, respectively @code{debug-here}, +@code{trace-here} and @code{trace-subtree}. + +@smalllisp +(break! . @var{args}) + @equiv{} (set-breakpoint! debug-here . @var{args}) +(trace! . @var{args}) + @equiv{} (set-breakpoint! trace-here . @var{args}) +(trace-subtree! . @var{args}) + @equiv{} (set-breakpoint! trace-subtree . @var{args}) +@end smalllisp + +This means that these three procedures can be used to set the +corresponding behaviours for any type of breakpoint for which a +@code{set-breakpoint!} method exists, not just procedural ones. + + +@node Accessing Breakpoints +@subsubsection Accessing Breakpoints + +Information about the state and behaviour of a breakpoint is stored in +an instance of the appropriate breakpoint class. To access and change +that information, therefore, you need to get hold of the desired +breakpoint instance. + +The generic function @code{get-breakpoint} meets this need: For every +@code{set-breakpoint!} method there is a corresponding +@code{get-breakpoint} method. Note especially the useful +type-independent case: + +@smalllisp +(get-breakpoint 1) +@result{} +#<<procedure-breakpoint> 808b0b0> +@end smalllisp + + +@node Breakpoint Behaviours +@subsubsection Breakpoint Behaviours + +A breakpoint's @dfn{behaviour} determines what happens when that +breakpoint is hit. Several kinds of behaviour are generally useful. + +@table @code +@item debug-here +Enter the command line debugger. This gives the opportunity to explore +the stack, evaluate expressions in any of the pending stack frames, +change breakpoint properties or set new breakpoints, and continue +program execution when you are done. + +@item trace-here +Trace the current stack frame. For expressions being evaluated, this +shows the expression. For procedure applications, it shows the +procedure name and its arguments @emph{post-evaluation}. For both +expressions and applications, the indentation of the tracing indicates +whether the traced items are mutually tail recursive. + +@item trace-subtree +Trace the current stack frame, and enable tracing for all future +evaluations and applications until the current stack frame is exited. +@code{trace-subtree} is a great preliminary exploration tool when all +you know is that there is a bug ``somewhere in XXX or in something that +XXX calls''. + +@item (at-exit @var{thunk}) +Don't do anything now, but arrange for @var{thunk} to be executed when +the current stack frame is exited. For example, the operation that most +debugging tools call ``finish'' is @code{(at-exit debug-here)}. + +@item (at-next @var{count} @var{thunk}) +@dots{} arrange for @var{thunk} to be executed when beginning the +@var{count}th next evaluation or application with source location in the +current file. + +@item (at-entry @var{count} @var{thunk}) +@dots{} arrange for @var{thunk} to be executed when beginning the +@var{count}th next evaluation (regardless of source location). + +@item (at-apply @var{count} @var{thunk}) +@dots{} arrange for @var{thunk} to be executed just before performing +the @var{count}th next application (regardless of source location). + +@item (at-step @var{count} @var{thunk}) +Synthesis of @code{at-entry} and @code{at-apply}; counts both +evaluations and applications. +@end table + +Every breakpoint instance has a slot in which its behaviour is stored. +If you have a breakpoint instance in hand, you can change its behaviour +using the @code{bp-behaviour} accessor. + +An @dfn{accessor} supports the setting of a property like this: + +@smalllisp +(set! (bp-behaviour @var{breakpoint}) @var{new-behaviour}) +@end smalllisp + +@noindent +See the GOOPS manual for further information on accessors. + +Alternatively, if you know how to specify the @var{location-args} for +the breakpoint in question, you can change its behaviour using +@code{set-breakpoint!}. For example: + +@smalllisp +;; Change behaviour of breakpoint number 2. +(set-breakpoint! @var{new-behaviour} 2) + +;; Change behaviour of procedural breakpoint on [fact1]. +(set-breakpoint! @var{new-behaviour} fact1) +@end smalllisp + +In all cases, the behaviour that you specify should be either a single +thunk, or a list of thunks, to be called when the breakpoint is hit. + +The most common behaviours above are exported as thunks from the +@code{(ice-9 debugger behaviour)} module. So, if you use this module, you can +use those behaviours directly like this: + +@smalllisp +(use-modules (ice-9 debugger behaviour)) +(set-breakpoint! trace-subtree 2) +(set! (bp-behaviour (get-breakpoint 3)) debug-here) +@end smalllisp + +@noindent +You can also use the list option to combine common behaviours: + +@smalllisp +(set-breakpoint! (list trace-here debug-here) 2) +@end smalllisp + +@noindent +Or, for more customized behaviour, you could build and use your own +thunk like this: + +@smalllisp +(define (my-behaviour) + (trace-here) + (at-exit (lambda () + (display "Exiting frame of my-behaviour bp\n") + ... do something unusual ...))) + +(set-breakpoint my-behaviour 2) +@end smalllisp + + +@node Enabling and Disabling +@subsubsection Enabling and Disabling + +Independently of its behaviour, each breakpoint also keeps track of +whether it is currently enabled. This is a straightforward convenience +to allow breakpoints to be temporarily switched off without losing all +their carefully constructed properties. + +If you have a breakpoint instance in hand, you can enable or disable it +using the @code{bp-enabled?} accessor. + +Alternatively, you can enable or disable a breakpoint via its location +args by using @code{enable-breakpoint!} or @code{disable-breakpoint!}. + +@smalllisp +(disable-breakpoint! fact1) ; disable the procedural breakpoint on fact1 +(enable-breakpoint! 1) ; enable breakpoint 1 +@end smalllisp + +@code{enable-breakpoint!} and @code{disable-breakpoint!} are implemented +using @code{get-breakpoint} and @code{bp-enabled?}, so any +@var{location-args} that are valid for @code{get-breakpoint} will work +also for these procedures. + + +@node Deleting Breakpoints +@subsubsection Deleting Breakpoints + +Given a breakpoint instance in hand, you can deactivate it and remove +it from the global list of current breakpoints by calling +@code{bp-delete!}. + +Alternatively, you can delete a breakpoint by its location args: + +@smalllisp +(delete-breakpoint! 1) ; delete breakpoint 1 +@end smalllisp + +@code{delete-breakpoint!} is implemented using @code{get-breakpoint} and +@code{bp-delete!}, so any @var{location-args} that are valid for +@code{get-breakpoint} will work also for @code{delete-breakpoint!}. + +There is no way to reinstate a deleted breakpoint. Final destruction of +the breakpoint instance is determined by the usual garbage collection +rules. + + +@node Breakpoint Information +@subsubsection Breakpoint Information + +To get Guile to print a description of a breakpoint instance, use +@code{bp-describe}: + +@smalllisp +(bp-describe (get-breakpoint 1) #t) ; #t specifies standard output +@print{} +Breakpoint 1: [fact1] + enabled? = #t + behaviour = #<procedure trace-here ()> +@end smalllisp + +Following the usual model, @code{describe-breakpoint} is also provided: + +@smalllisp +(describe-breakpoint 1) +@print{} +Breakpoint 1: [fact1] + enabled? = #t + behaviour = #<procedure trace-here ()> +@end smalllisp + +Finally, two stragglers. @code{all-breakpoints} returns a list of all +current breakpoints. @code{describe-all-breakpoints} combines +@code{bp-describe} and @code{all-breakpoints} by printing a description +of all current breakpoints to standard output. + +@node Other Breakpoint Types +@subsubsection Other Breakpoint Types + +Besides source and procedural breakpoints, Guile includes an early +implementation of a third class of breakpoints: @dfn{range} breakpoints. +These are breakpoints that trigger when program execution enters (or +perhaps exits) a defined range of source locations. + +Sadly, these don't yet work well. The apparent problem is that the +extra methods for @code{set-breakpoint!} and @code{get-breakpoint} cause +some kind of explosion in the time taken by GOOPS to construct its +method cache and to dispatch calls involving these generic functions. +But we haven't really investigated enough to be sure that this is the +real issue. + +If you're interested in looking and/or investigating anyway, please feel +free to check out and play with the @code{(ice-9 debugger breakpoints +range)} module. + +The other kind of breakpoint that we'd like to have is watchpoints, but +this hasn't been implemented at all yet. Watchpoints may turn out to be +impractical for performance reasons. + + +@node Interactive Debugger +@subsection Using the Interactive Debugger + +Guile's interactive debugger is a command line application that accepts +commands from you for examining the stack and, if at a breakpoint, for +continuing program execution in various ways. Unlike in the normal +Guile REPL, commands are typed mostly without parentheses. + +When you first enter the debugger, it introduces itself with a message +like this: + +@lisp +This is the Guile debugger -- for help, type `help'. +There are 3 frames on the stack. + +Frame 2 at standard input:36:19 + [+ 3 #\s] +debug> +@end lisp + +@noindent +``debug>'' is the debugger's prompt, and a useful reminder that you are +not in the normal Guile REPL. The available commands are described in +detail in the following subsections. + +@menu +* Display Backtrace:: backtrace. +* Frame Selection:: up, down, frame. +* Frame Information:: info args, info frame, position. +* Frame Evaluation:: evaluate. +* Single Stepping:: step, next. +* Run To Frame Exit:: finish, trace-finish. +* Continue Execution:: continue. +* Leave Debugger:: quit. +@end menu + + +@node Display Backtrace +@subsubsection Display Backtrace + +The @code{backtrace} command, which can also be invoked as @code{bt} or +@code{where}, displays the call stack (aka backtrace) at the point where +the debugger was entered: + +@lisp +debug> bt +In standard input: + 36: 0* [make-string ... + 36: 1* [* 4 ... + 36: 2* [+ 3 #\s] +@end lisp + +@deffn {Debugger Command} backtrace [count] +@deffnx {Debugger Command} bt [count] +@deffnx {Debugger Command} where [count] +Print backtrace of all stack frames, or of the innermost @var{count} +frames. With a negative argument, print the outermost -@var{count} +frames. If the number of frames isn't explicitly given, the debug +option @code{depth} determines the maximum number of frames printed. +@end deffn + +The format of the displayed backtrace is the same as for the +@code{backtrace} procedure --- see @ref{Backtrace Format} for details. + + +@node Frame Selection +@subsubsection Frame Selection + +A call stack consists of a sequence of stack @dfn{frames}, with each +frame describing one level of the nested evaluations and applications +that the program was executing when it hit a breakpoint or an error. +Frames are numbered such that frame 0 is the outermost --- i.e. the +operation on the call stack that began least recently --- and frame N-1 +the innermost (where N is the total number of frames on the stack). + +When you enter the debugger, the innermost frame is selected, which +means that the commands for getting information about the ``current'' +frame, or for evaluating expressions in the context of the current +frame, will do so by default with respect to the innermost frame. To +select a different frame, so that these operations will apply to it +instead, use the @code{up}, @code{down} and @code{frame} commands like +this: + +@lisp +debug> up +Frame 1 at standard input:36:14 + [* 4 ... +debug> frame 0 +Frame 0 at standard input:36:1 + [make-string ... +debug> down +Frame 1 at standard input:36:14 + [* 4 ... +@end lisp + +@deffn {Debugger Command} up [n] +Move @var{n} frames up the stack. For positive @var{n}, this +advances toward the outermost frame, to higher frame numbers, to +frames that have existed longer. @var{n} defaults to one. +@end deffn + +@deffn {Debugger Command} down [n] +Move @var{n} frames down the stack. For positive @var{n}, this +advances toward the innermost frame, to lower frame numbers, to frames +that were created more recently. @var{n} defaults to one. +@end deffn + +@deffn {Debugger Command} frame [n] +Select and print a stack frame. With no argument, print the selected +stack frame. (See also ``info frame''.) An argument specifies the +frame to select; it must be a stack-frame number. +@end deffn + + +@node Frame Information +@subsubsection Frame Information + +[to be completed] + +@deffn {Debugger Command} {info frame} +All about selected stack frame. +@end deffn + +@deffn {Debugger Command} {info args} +Argument variables of current stack frame. +@end deffn + +@deffn {Debugger Command} position +Display the position of the current expression. +@end deffn + + +@node Frame Evaluation +@subsubsection Frame Evaluation + +[to be completed] + +@deffn {Debugger Command} evaluate expression +Evaluate an expression. +The expression must appear on the same line as the command, +however it may be continued over multiple lines. +@end deffn + + +@node Single Stepping +@subsubsection Single Stepping + +[to be completed] + +@deffn {Debugger Command} step [n] +Continue until entry to @var{n}th next frame. +@end deffn + +@deffn {Debugger Command} next [n] +Continue until entry to @var{n}th next frame in same file. +@end deffn + + +@node Run To Frame Exit +@subsubsection Run To Frame Exit + +[to be completed] + +@deffn {Debugger Command} finish +Continue until evaluation of the current frame is complete, and +print the result obtained. +@end deffn + +@deffn {Debugger Command} trace-finish +Trace until evaluation of the current frame is complete. +@end deffn + + +@node Continue Execution +@subsubsection Continue Execution + +[to be completed] + +@deffn {Debugger Command} continue +Continue program execution. +@end deffn + + +@node Leave Debugger +@subsubsection Leave Debugger + +[to be completed] + +@deffn {Debugger Command} quit +Exit the debugger. +@end deffn + + +@node Tracing +@subsection Tracing + +Tracing has already been described as a breakpoint behaviour +(@pxref{Breakpoint Behaviours}), but we mention it again here because it +is so useful, and because Guile actually now has @emph{two} mechanisms +for tracing, and its worth clarifying the differences between them. + +@menu +* Old Tracing:: Tracing provided by (ice-9 debug). +* New Tracing:: Breakpoint-based tracing. +* Tracing Compared:: Differences between old and new. +@end menu + + +@node Old Tracing +@subsubsection Tracing Provided by @code{(ice-9 debug)} + +The @code{(ice-9 debug)} module implements tracing of procedure +applications. When a procedure is @dfn{traced}, it means that every +call to that procedure is reported to the user during a program run. +The idea is that you can mark a collection of procedures for tracing, +and Guile will subsequently print out a line of the form + +@smalllisp +| | [@var{procedure} @var{args} @dots{}] +@end smalllisp + +whenever a marked procedure is about to be applied to its arguments. +This can help a programmer determine whether a function is being called +at the wrong time or with the wrong set of arguments. + +In addition, the indentation of the output is useful for demonstrating +how the traced applications are or are not tail recursive with respect +to each other. Thus, a trace of a non-tail recursive factorial +implementation looks like this: + +@smalllisp +[fact1 4] +| [fact1 3] +| | [fact1 2] +| | | [fact1 1] +| | | | [fact1 0] +| | | | 1 +| | | 1 +| | 2 +| 6 +24 +@end smalllisp + +While a typical tail recursive implementation would look more like this: + +@smalllisp +[fact2 4] +[facti 1 4] +[facti 4 3] +[facti 12 2] +[facti 24 1] +[facti 24 0] +24 +@end smalllisp + +@deffn {Scheme Procedure} trace procedure +Enable tracing for @code{procedure}. While a program is being run, +Guile will print a brief report at each call to a traced procedure, +advising the user which procedure was called and the arguments that were +passed to it. +@end deffn + +@deffn {Scheme Procedure} untrace procedure +Disable tracing for @code{procedure}. +@end deffn + +Here is another example: + +@lisp +(define (rev ls) + (if (null? ls) + '() + (append (rev (cdr ls)) + (cons (car ls) '())))) @result{} rev + +(trace rev) @result{} (rev) + +(rev '(a b c d e)) +@result{} [rev (a b c d e)] + | [rev (b c d e)] + | | [rev (c d e)] + | | | [rev (d e)] + | | | | [rev (e)] + | | | | | [rev ()] + | | | | | () + | | | | (e) + | | | (e d) + | | (e d c) + | (e d c b) + (e d c b a) + (e d c b a) +@end lisp + +Note the way Guile indents the output, illustrating the depth of +execution at each procedure call. This can be used to demonstrate, for +example, that Guile implements self-tail-recursion properly: + +@lisp +(define (rev ls sl) + (if (null? ls) + sl + (rev (cdr ls) + (cons (car ls) sl)))) @result{} rev + +(trace rev) @result{} (rev) + +(rev '(a b c d e) '()) +@result{} [rev (a b c d e) ()] + [rev (b c d e) (a)] + [rev (c d e) (b a)] + [rev (d e) (c b a)] + [rev (e) (d c b a)] + [rev () (e d c b a)] + (e d c b a) + (e d c b a) +@end lisp + +Since the tail call is effectively optimized to a @code{goto} statement, +there is no need for Guile to create a new stack frame for each +iteration. Tracing reveals this optimization in operation. + + +@node New Tracing +@subsubsection Breakpoint-based Tracing + +Guile's newer mechanism implements tracing as an optional behaviour for +any kind of breakpoint. + +To trace a procedure (in the same kind of way as the older tracing), use +the @code{trace!} procedure to set a procedure breakpoint with +@code{trace-here} behaviour: + +@lisp +(trace! fact1) +@print{} +Set breakpoint 1: [fact1] +@result{} +#<<procedure-breakpoint> 40337bf0> + +(fact1 4) +@print{} +| [fact1 4] +| | [fact1 3] +| | | [fact1 2] +| | | | [fact1 1] +| | | | | [fact1 0] +| | | | | 1 +| | | | 2 +| | | 6 +| | 24 +| 24 +@result{} +24 +@end lisp + +To trace evaluation of a source expression, evaluate code containing a +breakpoint marker @code{##} in the appropriate place, then use +@code{set-breakpoint} to change the behaviour of the new breakpoint to +@code{trace-here}: + +@lisp +(define (fact1 n) + (if ##(= n 0) + 1 + (* n (fact1 (- n 1))))) +@print{} +Set breakpoint 4: standard input:13:9: (= n 0) + +(use-modules (ice-9 debugger behaviour)) +(set-breakpoint! trace-here 4) +@print{} +Breakpoint 4: standard input:13:9: (= n 0) + enabled? = #t + behaviour = #<procedure trace-here ()> + +(fact1 4) +@print{} +| (= n 0) +| #f +| (= n 0) +| #f +| (= n 0) +| #f +| (= n 0) +| #f +| (= n 0) +| #t +@result{} +24 +@end lisp + +@noindent +(Note --- this example reveals a bug: each occurrence of @code{(= n 0)} +should be shown indented with respect to the one before it, as +@code{fact1} does not call itself tail-recursively.) + +You can also give a breakpoint the @code{trace-subtree} behaviour, which +means to trace the breakpoint location itself plus any evaluations and +applications that occur below it in the call stack. In the following +example, this allows us to see the evaluated arguments that are being +compared by the @code{=} procedure: + +@lisp +(set-breakpoint! trace-subtree 4) +@print{} +Breakpoint 4: standard input:13:9: (= n 0) + enabled? = #t + behaviour = #<procedure trace-subtree ()> + +(fact1 4) +@print{} +| (= n 0) +| [= 4 0] +| #f +| (= n 0) +| [= 3 0] +| #f +| (= n 0) +| [= 2 0] +| #f +| (= n 0) +| [= 1 0] +| #f +| (= n 0) +| [= 0 0] +| #t +@result{} +24 +@end lisp + + +@node Tracing Compared +@subsubsection Differences Between Old and New Tracing Mechanisms + +The newer tracing mechanism is more general and so more powerful than +the older one: it works for expressions as well as procedure +applications, and it implements the useful @code{trace-subtree} +behaviour as well as the more traditional @code{trace-here}. + +The older mechanism will probably become obsolete eventually, but it's +worth keeping it around for a while until we are sure that the new +mechanism is correct and does what programmers need. diff --git a/doc/ref/scheme-evaluation.texi b/doc/ref/scheme-evaluation.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-evaluation.texi +++ /dev/null diff --git a/doc/ref/scheme-io.texi b/doc/ref/scheme-io.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-io.texi +++ /dev/null diff --git a/doc/ref/scheme-memory.texi b/doc/ref/scheme-memory.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-memory.texi +++ /dev/null diff --git a/doc/ref/scheme-modules.texi b/doc/ref/scheme-modules.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-modules.texi +++ /dev/null diff --git a/doc/ref/scheme-options.texi b/doc/ref/scheme-options.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-options.texi +++ /dev/null diff --git a/doc/ref/scheme-procedures.texi b/doc/ref/scheme-procedures.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-procedures.texi +++ /dev/null diff --git a/doc/ref/scheme-scheduling.texi b/doc/ref/scheme-scheduling.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-scheduling.texi +++ /dev/null diff --git a/doc/ref/scheme-scm.texi b/doc/ref/scheme-scm.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-scm.texi +++ /dev/null diff --git a/doc/ref/scheme-scripts.texi b/doc/ref/scheme-scripts.texi new file mode 100644 index 000000000..ec1675ec2 --- /dev/null +++ b/doc/ref/scheme-scripts.texi @@ -0,0 +1,508 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@page +@node Guile Scripting +@section Guile Scripting + +Like AWK, Perl, or any shell, Guile can interpret script files. A Guile +script is simply a file of Scheme code with some extra information at +the beginning which tells the operating system how to invoke Guile, and +then tells Guile how to handle the Scheme code. + +@menu +* The Top of a Script File:: How to start a Guile script. +* Invoking Guile:: Command line options understood by Guile. +* The Meta Switch:: Passing complex argument lists to Guile + from shell scripts. +* Command Line Handling:: Accessing the command line from a script. +* Scripting Examples:: +@end menu + + +@node The Top of a Script File +@subsection The Top of a Script File + +The first line of a Guile script must tell the operating system to use +Guile to evaluate the script, and then tell Guile how to go about doing +that. Here is the simplest case: + +@itemize @bullet + +@item +The first two characters of the file must be @samp{#!}. + +The operating system interprets this to mean that the rest of the line +is the name of an executable that can interpret the script. Guile, +however, interprets these characters as the beginning of a multi-line +comment, terminated by the characters @samp{!#} on a line by themselves. +(This is an extension to the syntax described in R5RS, added to support +shell scripts.) + +@item +Immediately after those two characters must come the full pathname to +the Guile interpreter. On most systems, this would be +@samp{/usr/local/bin/guile}. + +@item +Then must come a space, followed by a command-line argument to pass to +Guile; this should be @samp{-s}. This switch tells Guile to run a +script, instead of soliciting the user for input from the terminal. +There are more elaborate things one can do here; see @ref{The Meta +Switch}. + +@item +Follow this with a newline. + +@item +The second line of the script should contain only the characters +@samp{!#} --- just like the top of the file, but reversed. The +operating system never reads this far, but Guile treats this as the end +of the comment begun on the first line by the @samp{#!} characters. + +@item +The rest of the file should be a Scheme program. + +@end itemize + +Guile reads the program, evaluating expressions in the order that they +appear. Upon reaching the end of the file, Guile exits. + + +@node Invoking Guile +@subsection Invoking Guile + +Here we describe Guile's command-line processing in detail. Guile +processes its arguments from left to right, recognizing the switches +described below. For examples, see @ref{Scripting Examples}. + +@table @code + +@item -s @var{script} @var{arg...} +Read and evaluate Scheme source code from the file @var{script}, as the +@code{load} function would. After loading @var{script}, exit. Any +command-line arguments @var{arg...} following @var{script} become the +script's arguments; the @code{command-line} function returns a list of +strings of the form @code{(@var{script} @var{arg...})}. + +@item -c @var{expr} @var{arg...} +Evaluate @var{expr} as Scheme code, and then exit. Any command-line +arguments @var{arg...} following @var{expr} become command-line arguments; the +@code{command-line} function returns a list of strings of the form +@code{(@var{guile} @var{arg...})}, where @var{guile} is the path of the +Guile executable. + +@item -- @var{arg...} +Run interactively, prompting the user for expressions and evaluating +them. Any command-line arguments @var{arg...} following the @code{--} +become command-line arguments for the interactive session; the +@code{command-line} function returns a list of strings of the form +@code{(@var{guile} @var{arg...})}, where @var{guile} is the path of the +Guile executable. + +@item -l @var{file} +Load Scheme source code from @var{file}, and continue processing the +command line. + +@item -e @var{function} +Make @var{function} the @dfn{entry point} of the script. After loading +the script file (with @code{-s}) or evaluating the expression (with +@code{-c}), apply @var{function} to a list containing the program name +and the command-line arguments --- the list provided by the +@code{command-line} function. + +A @code{-e} switch can appear anywhere in the argument list, but Guile +always invokes the @var{function} as the @emph{last} action it performs. +This is weird, but because of the way script invocation works under +POSIX, the @code{-s} option must always come last in the list. + +The @var{function} is most often a simple symbol that names a function +that is defined in the script. It can also be of the form @code{(@@ +@var{module-name} @var{symbol})} and in that case, the symbol is +looked up in the module named @var{module-name}. + +@xref{Scripting Examples}. + +@item -ds +Treat a final @code{-s} option as if it occurred at this point in the +command line; load the script here. + +This switch is necessary because, although the POSIX script invocation +mechanism effectively requires the @code{-s} option to appear last, the +programmer may well want to run the script before other actions +requested on the command line. For examples, see @ref{Scripting +Examples}. + +@item \ +Read more command-line arguments, starting from the second line of the +script file. @xref{The Meta Switch}. + +@item --emacs +Assume Guile is running as an inferior process of Emacs, and use a +special protocol to communicate with Emacs's Guile interaction mode. +This switch sets the global variable use-emacs-interface to @code{#t}. + +This switch is still experimental. + +@item --use-srfi=@var{list} +The option @code{--use-srfi} expects a comma-separated list of numbers, +each representing a SRFI number to be loaded into the interpreter +before starting evaluating a script file or the REPL. Additionally, +the feature identifier for the loaded SRFIs is recognized by +`cond-expand' when using this option. + +@example +guile --use-srfi=8,13 +@end example + +@item --debug +Start with the debugging evaluator and enable backtraces. Using the +debugging evaluator will give you better error messages but it will +slow down execution. By default, the debugging evaluator is only used +when entering an interactive session. When executing a script with +@code{-s} or @code{-c}, the normal, faster evaluator is used by default. + +@vnew{1.8} +@item --no-debug +Do not use the debugging evaluator, even when entering an interactive +session. + +@item -h@r{, }--help +Display help on invoking Guile, and then exit. + +@item -v@r{, }--version +Display the current version of Guile, and then exit. + +@end table + + +@node The Meta Switch +@subsection The Meta Switch + +Guile's command-line switches allow the programmer to describe +reasonably complicated actions in scripts. Unfortunately, the POSIX +script invocation mechanism only allows one argument to appear on the +@samp{#!} line after the path to the Guile executable, and imposes +arbitrary limits on that argument's length. Suppose you wrote a script +starting like this: +@example +#!/usr/local/bin/guile -e main -s +!# +(define (main args) + (map (lambda (arg) (display arg) (display " ")) + (cdr args)) + (newline)) +@end example +The intended meaning is clear: load the file, and then call @code{main} +on the command-line arguments. However, the system will treat +everything after the Guile path as a single argument --- the string +@code{"-e main -s"} --- which is not what we want. + +As a workaround, the meta switch @code{\} allows the Guile programmer to +specify an arbitrary number of options without patching the kernel. If +the first argument to Guile is @code{\}, Guile will open the script file +whose name follows the @code{\}, parse arguments starting from the +file's second line (according to rules described below), and substitute +them for the @code{\} switch. + +Working in concert with the meta switch, Guile treats the characters +@samp{#!} as the beginning of a comment which extends through the next +line containing only the characters @samp{!#}. This sort of comment may +appear anywhere in a Guile program, but it is most useful at the top of +a file, meshing magically with the POSIX script invocation mechanism. + +Thus, consider a script named @file{/u/jimb/ekko} which starts like this: +@example +#!/usr/local/bin/guile \ +-e main -s +!# +(define (main args) + (map (lambda (arg) (display arg) (display " ")) + (cdr args)) + (newline)) +@end example + +Suppose a user invokes this script as follows: +@example +$ /u/jimb/ekko a b c +@end example + +Here's what happens: +@itemize @bullet + +@item +the operating system recognizes the @samp{#!} token at the top of the +file, and rewrites the command line to: +@example +/usr/local/bin/guile \ /u/jimb/ekko a b c +@end example +This is the usual behavior, prescribed by POSIX. + +@item +When Guile sees the first two arguments, @code{\ /u/jimb/ekko}, it opens +@file{/u/jimb/ekko}, parses the three arguments @code{-e}, @code{main}, +and @code{-s} from it, and substitutes them for the @code{\} switch. +Thus, Guile's command line now reads: +@example +/usr/local/bin/guile -e main -s /u/jimb/ekko a b c +@end example + +@item +Guile then processes these switches: it loads @file{/u/jimb/ekko} as a +file of Scheme code (treating the first three lines as a comment), and +then performs the application @code{(main "/u/jimb/ekko" "a" "b" "c")}. + +@end itemize + + +When Guile sees the meta switch @code{\}, it parses command-line +argument from the script file according to the following rules: +@itemize @bullet + +@item +Each space character terminates an argument. This means that two +spaces in a row introduce an argument @code{""}. + +@item +The tab character is not permitted (unless you quote it with the +backslash character, as described below), to avoid confusion. + +@item +The newline character terminates the sequence of arguments, and will +also terminate a final non-empty argument. (However, a newline +following a space will not introduce a final empty-string argument; +it only terminates the argument list.) + +@item +The backslash character is the escape character. It escapes backslash, +space, tab, and newline. The ANSI C escape sequences like @code{\n} and +@code{\t} are also supported. These produce argument constituents; the +two-character combination @code{\n} doesn't act like a terminating +newline. The escape sequence @code{\@var{NNN}} for exactly three octal +digits reads as the character whose ASCII code is @var{NNN}. As above, +characters produced this way are argument constituents. Backslash +followed by other characters is not allowed. + +@end itemize + + +@node Command Line Handling +@subsection Command Line Handling + +@c This section was written and contributed by Martin Grabmueller. + +The ability to accept and handle command line arguments is very +important when writing Guile scripts to solve particular problems, such +as extracting information from text files or interfacing with existing +command line applications. This chapter describes how Guile makes +command line arguments available to a Guile script, and the utilities +that Guile provides to help with the processing of command line +arguments. + +When a Guile script is invoked, Guile makes the command line arguments +accessible via the procedure @code{command-line}, which returns the +arguments as a list of strings. + +For example, if the script + +@example +#! /usr/local/bin/guile -s +!# +(write (command-line)) +(newline) +@end example + +@noindent +is saved in a file @file{cmdline-test.scm} and invoked using the command +line @code{./cmdline-test.scm bar.txt -o foo -frumple grob}, the output +is + +@example +("./cmdline-test.scm" "bar.txt" "-o" "foo" "-frumple" "grob") +@end example + +If the script invocation includes a @code{-e} option, specifying a +procedure to call after loading the script, Guile will call that +procedure with @code{(command-line)} as its argument. So a script that +uses @code{-e} doesn't need to refer explicitly to @code{command-line} +in its code. For example, the script above would have identical +behaviour if it was written instead like this: + +@example +#! /usr/local/bin/guile \ +-e main -s +!# +(define (main args) + (write args) + (newline)) +@end example + +(Note the use of the meta switch @code{\} so that the script invocation +can include more than one Guile option: @xref{The Meta Switch}.) + +These scripts use the @code{#!} POSIX convention so that they can be +executed using their own file names directly, as in the example command +line @code{./cmdline-test.scm bar.txt -o foo -frumple grob}. But they +can also be executed by typing out the implied Guile command line in +full, as in: + +@example +$ guile -s ./cmdline-test.scm bar.txt -o foo -frumple grob +@end example + +@noindent +or + +@example +$ guile -e main -s ./cmdline-test2.scm bar.txt -o foo -frumple grob +@end example + +Even when a script is invoked using this longer form, the arguments that +the script receives are the same as if it had been invoked using the +short form. Guile ensures that the @code{(command-line)} or @code{-e} +arguments are independent of how the script is invoked, by stripping off +the arguments that Guile itself processes. + +A script is free to parse and handle its command line arguments in any +way that it chooses. Where the set of possible options and arguments is +complex, however, it can get tricky to extract all the options, check +the validity of given arguments, and so on. This task can be greatly +simplified by taking advantage of the module @code{(ice-9 getopt-long)}, +which is distributed with Guile, @xref{getopt-long}. + + +@node Scripting Examples +@subsection Scripting Examples + +To start with, here are some examples of invoking Guile directly: + +@table @code + +@item guile -- a b c +Run Guile interactively; @code{(command-line)} will return @* +@code{("/usr/local/bin/guile" "a" "b" "c")}. + +@item guile -s /u/jimb/ex2 a b c +Load the file @file{/u/jimb/ex2}; @code{(command-line)} will return @* +@code{("/u/jimb/ex2" "a" "b" "c")}. + +@item guile -c '(write %load-path) (newline)' +Write the value of the variable @code{%load-path}, print a newline, +and exit. + +@item guile -e main -s /u/jimb/ex4 foo +Load the file @file{/u/jimb/ex4}, and then call the function +@code{main}, passing it the list @code{("/u/jimb/ex4" "foo")}. + +@item guile -l first -ds -l last -s script +Load the files @file{first}, @file{script}, and @file{last}, in that +order. The @code{-ds} switch says when to process the @code{-s} +switch. For a more motivated example, see the scripts below. + +@end table + + +Here is a very simple Guile script: +@example +#!/usr/local/bin/guile -s +!# +(display "Hello, world!") +(newline) +@end example +The first line marks the file as a Guile script. When the user invokes +it, the system runs @file{/usr/local/bin/guile} to interpret the script, +passing @code{-s}, the script's filename, and any arguments given to the +script as command-line arguments. When Guile sees @code{-s +@var{script}}, it loads @var{script}. Thus, running this program +produces the output: +@example +Hello, world! +@end example + +Here is a script which prints the factorial of its argument: +@example +#!/usr/local/bin/guile -s +!# +(define (fact n) + (if (zero? n) 1 + (* n (fact (- n 1))))) + +(display (fact (string->number (cadr (command-line))))) +(newline) +@end example +In action: +@example +$ fact 5 +120 +$ +@end example + +However, suppose we want to use the definition of @code{fact} in this +file from another script. We can't simply @code{load} the script file, +and then use @code{fact}'s definition, because the script will try to +compute and display a factorial when we load it. To avoid this problem, +we might write the script this way: + +@example +#!/usr/local/bin/guile \ +-e main -s +!# +(define (fact n) + (if (zero? n) 1 + (* n (fact (- n 1))))) + +(define (main args) + (display (fact (string->number (cadr args)))) + (newline)) +@end example +This version packages the actions the script should perform in a +function, @code{main}. This allows us to load the file purely for its +definitions, without any extraneous computation taking place. Then we +used the meta switch @code{\} and the entry point switch @code{-e} to +tell Guile to call @code{main} after loading the script. +@example +$ fact 50 +30414093201713378043612608166064768844377641568960512000000000000 +@end example + +Suppose that we now want to write a script which computes the +@code{choose} function: given a set of @var{m} distinct objects, +@code{(choose @var{n} @var{m})} is the number of distinct subsets +containing @var{n} objects each. It's easy to write @code{choose} given +@code{fact}, so we might write the script this way: +@example +#!/usr/local/bin/guile \ +-l fact -e main -s +!# +(define (choose n m) + (/ (fact m) (* (fact (- m n)) (fact n)))) + +(define (main args) + (let ((n (string->number (cadr args))) + (m (string->number (caddr args)))) + (display (choose n m)) + (newline))) +@end example + +The command-line arguments here tell Guile to first load the file +@file{fact}, and then run the script, with @code{main} as the entry +point. In other words, the @code{choose} script can use definitions +made in the @code{fact} script. Here are some sample runs: +@example +$ choose 0 4 +1 +$ choose 1 4 +4 +$ choose 2 4 +6 +$ choose 3 4 +4 +$ choose 4 4 +1 +$ choose 50 100 +100891344545564193334812497256 +@end example + diff --git a/doc/ref/scheme-smobs.texi b/doc/ref/scheme-smobs.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-smobs.texi +++ /dev/null diff --git a/doc/ref/scheme-snarf.texi b/doc/ref/scheme-snarf.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-snarf.texi +++ /dev/null diff --git a/doc/ref/scheme-translation.texi b/doc/ref/scheme-translation.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-translation.texi +++ /dev/null diff --git a/doc/ref/scheme-utility.texi b/doc/ref/scheme-utility.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scheme-utility.texi +++ /dev/null diff --git a/doc/ref/scm.texi b/doc/ref/scm.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scm.texi +++ /dev/null diff --git a/doc/ref/scripts.texi b/doc/ref/scripts.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ref/scripts.texi +++ /dev/null |