diff options
author | Neil Jerram <neil@ossau.uklinux.net> | 2001-08-24 09:40:29 +0000 |
---|---|---|
committer | Neil Jerram <neil@ossau.uklinux.net> | 2001-08-24 09:40:29 +0000 |
commit | a0e07ba4ec86e4df014fee0666f18ece5a4d2471 (patch) | |
tree | ebe6546fc93fdcb3e2e1fdfbe55d809914b94ad8 | |
parent | 80fdeb4e5a869726da90c88ddce377f599515ee8 (diff) | |
download | guile-a0e07ba4ec86e4df014fee0666f18ece5a4d2471.tar.gz |
* Organize documentation into per-manual directories (halfway point commit).
99 files changed, 36066 insertions, 4 deletions
diff --git a/doc/ChangeLog-guile-doc-ref b/doc/ChangeLog-guile-doc-ref deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ChangeLog-guile-doc-ref +++ /dev/null diff --git a/doc/ChangeLog-guile-doc-tutorial b/doc/ChangeLog-guile-doc-tutorial deleted file mode 100644 index e69de29bb..000000000 --- a/doc/ChangeLog-guile-doc-tutorial +++ /dev/null diff --git a/doc/api.txt b/doc/api.txt deleted file mode 100644 index e69de29bb..000000000 --- a/doc/api.txt +++ /dev/null diff --git a/doc/deprecated.texi b/doc/deprecated.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/deprecated.texi +++ /dev/null diff --git a/doc/expect.texi b/doc/expect.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/expect.texi +++ /dev/null diff --git a/doc/extend.texi b/doc/extend.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/extend.texi +++ /dev/null diff --git a/doc/format.texi b/doc/format.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/format.texi +++ /dev/null diff --git a/doc/gh.texi b/doc/gh.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/gh.texi +++ /dev/null diff --git a/doc/goops-tutorial.texi b/doc/goops-tutorial.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/goops-tutorial.texi +++ /dev/null diff --git a/doc/goops.texi b/doc/goops.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/goops.texi +++ /dev/null diff --git a/doc/goops/.cvsignore b/doc/goops/.cvsignore new file mode 100644 index 000000000..8eaa8267a --- /dev/null +++ b/doc/goops/.cvsignore @@ -0,0 +1,23 @@ +Makefile +Makefile.in +stamp-vti +stamp-vti.1 +*.log +*.dvi +*.aux +*.toc +*.cp +*.fn +*.vr +*.tp +*.ky +*.pg +*.cps +*.fns +*.tps +*.vrs +*.ps +*.info* +*.html +version.texi +version-tutorial.texi diff --git a/doc/goops/goops-tutorial.texi b/doc/goops/goops-tutorial.texi new file mode 100644 index 000000000..7ab6ebcf0 --- /dev/null +++ b/doc/goops/goops-tutorial.texi @@ -0,0 +1,810 @@ +@c Original attribution: + +@c +@c STk Reference manual (Appendix: An Introduction to STklos) +@c +@c Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr> +@c Permission to use, copy, modify, distribute,and license this +@c software and its documentation for any purpose is hereby granted, +@c provided that existing copyright notices are retained in all +@c copies and that this notice is included verbatim in any +@c distributions. No written agreement, license, or royalty fee is +@c required for any of the authorized uses. +@c This software is provided ``AS IS'' without express or implied +@c warranty. +@c + +@c Adapted for use in Guile with the authors permission + +@c @macro goops @c was {\stklos} +@c GOOPS +@c @end macro + +@c @macro guile @c was {\stk} +@c Guile +@c @end macro + +This is chapter was originally written by Erick Gallesio as an appendix +for the STk reference manual, and subsequently adapted to @goops{}. + +@menu +* Copyright:: +* Intro:: +* Class definition and instantiation:: +* Inheritance:: +* Generic functions:: +@end menu + +@node Copyright, Intro, Tutorial, Tutorial +@section Copyright + +Original attribution: + +STk Reference manual (Appendix: An Introduction to STklos) + +Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@@unice.fr> +Permission to use, copy, modify, distribute,and license this +software and its documentation for any purpose is hereby granted, +provided that existing copyright notices are retained in all +copies and that this notice is included verbatim in any +distributions. No written agreement, license, or royalty fee is +required for any of the authorized uses. +This software is provided ``AS IS'' without express or implied +warranty. + +Adapted for use in Guile with the authors permission + +@node Intro, Class definition and instantiation, Copyright, Tutorial +@section Introduction + +@goops{} is the object oriented extension to @guile{}. Its +implementation is derived from @w{STk-3.99.3} by Erick Gallesio and +version 1.3 of the Gregor Kiczales @cite{Tiny-Clos}. It is very close +to CLOS, the Common Lisp Object System (@cite{CLtL2}) but is adapted for +the Scheme language. + +Briefly stated, the @goops{} extension gives the user a full object +oriented system with multiple inheritance and generic functions with +multi-method dispatch. Furthermore, the implementation relies on a true +meta object protocol, in the spirit of the one defined for CLOS +(@cite{Gregor Kiczales: A Metaobject Protocol}). + +The purpose of this tutorial is to introduce briefly the @goops{} +package and in no case will it replace the @goops{} reference manual +(which needs to be urgently written now@ @dots{}). + +Note that the operations described in this tutorial resides in modules +that may need to be imported before being available. The main module is +imported by evaluating: + +@lisp +(use-modules (oop goops)) +@end lisp +@findex (oop goops) +@cindex main module +@cindex loading +@cindex preparing + +@node Class definition and instantiation, Inheritance, Intro, Tutorial +@section Class definition and instantiation + +@menu +* Class definition:: +@end menu + +@node Class definition, , Class definition and instantiation, Class definition and instantiation +@subsection Class definition + +A new class is defined with the @code{define-class}@footnote{Don't +forget to import the @code{(oop goops)} module} macro. The syntax of +@code{define-class} is close to CLOS @code{defclass}: + +@findex define-class +@cindex class +@lisp +(define-class @var{class} (@var{superclass} @dots{}) + @var{slot-description} @dots{} + @var{class-option} @dots{}) +@end lisp + +Class options will not be discussed in this tutorial. The list of +@var{superclass}es specifies which classes to inherit properties from +@var{class} (see @ref{Inheritance} for more details). A +@var{slot-description} gives the name of a slot and, eventually, some +``properties'' of this slot (such as its initial value, the function +which permit to access its value, @dots{}). Slot descriptions will be +discussed in @ref{Slot description}. +@cindex slot + +As an example, let us define a type for representation of complex +numbers in terms of real numbers. This can be done with the following +class definition: + +@lisp +(define-class <complex> (<number>) + r i) +@end lisp + +This binds the variable @code{<complex>}@footnote{@code{<complex>} is in +fact a builtin class in GOOPS. Because of this, GOOPS will create a new +class. The old class will still serve as the type for Guile's native +complex numbers.} to a new class whose instances contain two +slots. These slots are called @code{r} an @code{i} and we suppose here +that they contain respectively the real part and the imaginary part of a +complex number. Note that this class inherits from @code{<number>} which +is a pre-defined class. (@code{<number>} is the direct super class of +the pre-defined class @code{<complex>} which, in turn, is the super +class of @code{<real>} which is the super of +@code{<integer>}.)@footnote{With the new definition of @code{<complex>}, +a @code{<real>} is not a @code{<complex>} since @code{<real>} inherits +from @code{ <number>} rather than @code{<complex>}. In practice, +inheritance could be modified @emph{a posteriori}, if needed. However, +this necessitates some knowledge of the meta object protocol and it will +not be shown in this document}. + +@node Inheritance, Generic functions, Class definition and instantiation, Tutorial +@section Inheritance +@c \label{inheritance} + +@menu +* Class hierarchy and inheritance of slots:: +* Instance creation and slot access:: +* Slot description:: +* Class precedence list:: +@end menu + +@node Class hierarchy and inheritance of slots, Instance creation and slot access, Inheritance, Inheritance +@subsection Class hierarchy and inheritance of slots +Inheritance is specified upon class definition. As said in the +introduction, @goops{} supports multiple inheritance. Here are some +class definitions: + +@lisp +(define-class A () a) +(define-class B () b) +(define-class C () c) +(define-class D (A B) d a) +(define-class E (A C) e c) +(define-class F (D E) f) +@end lisp + +@code{A}, @code{B}, @code{C} have a null list of super classes. In this +case, the system will replace it by the list which only contains +@code{<object>}, the root of all the classes defined by +@code{define-class}. @code{D}, @code{E}, @code{F} use multiple +inheritance: each class inherits from two previously defined classes. +Those class definitions define a hierarchy which is shown in Figure@ 1. +In this figure, the class @code{<top>} is also shown; this class is the +super class of all Scheme objects. In particular, @code{<top>} is the +super class of all standard Scheme types. + +@example +@group +@image{hierarchy} +@center @emph{Fig 1: A class hierarchy} +@iftex +@emph{(@code{<complex>} which is the direct subclass of @code{<number>} +and the direct superclass of @code{<real>} has been omitted in this +figure.)} +@end iftex +@end group +@end example + +The set of slots of a given class is calculated by taking the union of the +slots of all its super class. For instance, each instance of the class +D, defined before will have three slots (@code{a}, @code{b} and +@code{d}). The slots of a class can be obtained by the @code{class-slots} +primitive. For instance, + +@lisp +(class-slots A) @result{} ((a)) +(class-slots E) @result{} ((a) (e) (c)) +(class-slots F) @result{} ((e) (c) (b) (d) (a) (f)) +@c used to be ((d) (a) (b) (c) (f)) +@end lisp + +@emph{Note: } The order of slots is not significant. + +@node Instance creation and slot access, Slot description, Class hierarchy and inheritance of slots, Inheritance +@subsection Instance creation and slot access + +Creation of an instance of a previously defined +class can be done with the @code{make} procedure. This +procedure takes one mandatory parameter which is the class of the +instance which must be created and a list of optional +arguments. Optional arguments are generally used to initialize some +slots of the newly created instance. For instance, the following form + +@findex make +@cindex instance +@lisp +(define c (make <complex>)) +@end lisp + +will create a new @code{<complex>} object and will bind it to the @code{c} +Scheme variable. + +Accessing the slots of the new complex number can be done with the +@code{slot-ref} and the @code{slot-set!} primitives. @code{Slot-set!} +primitive permits to set the value of an object slot and @code{slot-ref} +permits to get its value. + +@findex slot-set! +@findex slot-ref +@lisp +@group +(slot-set! c 'r 10) +(slot-set! c 'i 3) +(slot-ref c 'r) @result{} 10 +(slot-ref c 'i) @result{} 3 +@end group +@end lisp + +Using the @code{describe} function is a simple way to see all the +slots of an object at one time: this function prints all the slots of an +object on the standard output. + +First load the module @code{(oop goops describe)}: + +@example +@code{(use-modules (oop goops describe))} +@end example + +The expression + +@smalllisp +(describe c) +@end smalllisp + +will now print the following information on the standard output: + +@lisp +#<<complex> 401d8638> is an instance of class <complex> +Slots are: + r = 10 + i = 3 +@end lisp + +@node Slot description, Class precedence list, Instance creation and slot access, Inheritance +@subsection Slot description +@c \label{slot-description} + +When specifying a slot, a set of options can be given to the +system. Each option is specified with a keyword. The list of authorized +keywords is given below: + +@cindex keyword +@itemize @bullet +@item +@code{#:init-value} permits to supply a default value for the slot. This +default value is obtained by evaluating the form given after the +@code{#:init-form} in the global environment, at class definition time. +@cindex default slot value +@findex #:init-value +@cindex top level environment + +@item +@code{#:init-thunk} permits to supply a thunk that will provide a +default value for the slot. The value is obtained by evaluating the +thunk a instance creation time. +@c CHECKME: in the global environment? +@findex default slot value +@findex #:init-thunk +@cindex top level environment + +@item +@code{#:init-keyword} permits to specify the keyword for initializing a +slot. The init-keyword may be provided during instance creation (i.e. in +the @code{make} optional parameter list). Specifying such a keyword +during instance initialization will supersede the default slot +initialization possibly given with @code{#:init-form}. +@findex #:init-keyword + +@item +@code{#:getter} permits to supply the name for the +slot getter. The name binding is done in the +environment of the @code{define-class} macro. +@findex #:getter +@cindex top level environment +@cindex getter + +@item +@code{#:setter} permits to supply the name for the +slot setter. The name binding is done in the +environment of the @code{define-class} macro. +@findex #:setter +@cindex top level environment +@cindex setter + +@item +@code{#:accessor} permits to supply the name for the +slot accessor. The name binding is done in the global +environment. An accessor permits to get and +set the value of a slot. Setting the value of a slot is done with the extended +version of @code{set!}. +@findex set! +@findex #:accessor +@cindex top level environment +@cindex accessor + +@item +@code{#:allocation} permits to specify how storage for +the slot is allocated. Three kinds of allocation are provided. +They are described below: + +@itemize @minus +@item +@code{#:instance} indicates that each instance gets its own storage for +the slot. This is the default. +@item +@code{#:class} indicates that there is one storage location used by all +the direct and indirect instances of the class. This permits to define a +kind of global variable which can be accessed only by (in)direct +instances of the class which defines this slot. +@item +@code{#:each-subclass} indicates that there is one storage location used +by all the direct instances of the class. In other words, if two classes +are not siblings in the class hierarchy, they will not see the same +value. +@item +@code{#:virtual} indicates that no storage will be allocated for this +slot. It is up to the user to define a getter and a setter function for +this slot. Those functions must be defined with the @code{#:slot-ref} +and @code{#:slot-set!} options. See the example below. +@findex #:slot-set! +@findex #:slot-ref +@findex #:virtual +@findex #:class +@findex #:each-subclass +@findex #:instance +@findex #:allocation +@end itemize +@end itemize + +To illustrate slot description, we shall redefine the @code{<complex>} class +seen before. A definition could be: + +@lisp +(define-class <complex> (<number>) + (r #:init-value 0 #:getter get-r #:setter set-r! #:init-keyword #:r) + (i #:init-value 0 #:getter get-i #:setter set-i! #:init-keyword #:i)) +@end lisp + +With this definition, the @code{r} and @code{i} slot are set to 0 by +default. Value of a slot can also be specified by calling @code{make} +with the @code{#:r} and @code{#:i} keywords. Furthermore, the generic +functions @code{get-r} and @code{set-r!} (resp. @code{get-i} and +@code{set-i!}) are automatically defined by the system to read and write +the @code{r} (resp. @code{i}) slot. + +@lisp +(define c1 (make <complex> #:r 1 #:i 2)) +(get-r c1) @result{} 1 +(set-r! c1 12) +(get-r c1) @result{} 12 +(define c2 (make <complex> #:r 2)) +(get-r c2) @result{} 2 +(get-i c2) @result{} 0 +@end lisp + +Accessors provide an uniform access for reading and writing an object +slot. Writing a slot is done with an extended form of @code{set!} +which is close to the Common Lisp @code{setf} macro. So, another +definition of the previous @code{<complex>} class, using the +@code{#:accessor} option, could be: + +@findex set! +@lisp +(define-class <complex> (<number>) + (r #:init-value 0 #:accessor real-part #:init-keyword #:r) + (i #:init-value 0 #:accessor imag-part #:init-keyword #:i)) +@end lisp + +Using this class definition, reading the real part of the @code{c} +complex can be done with: +@lisp +(real-part c) +@end lisp +and setting it to the value contained in the @code{new-value} variable +can be done using the extended form of @code{set!}. +@lisp +(set! (real-part c) new-value) +@end lisp + +Suppose now that we have to manipulate complex numbers with rectangular +coordinates as well as with polar coordinates. One solution could be to +have a definition of complex numbers which uses one particular +representation and some conversion functions to pass from one +representation to the other. A better solution uses virtual slots. A +complete definition of the @code{<complex>} class using virtual slots is +given in Figure@ 2. + +@example +@group +@lisp +(define-class <complex> (<number>) + ;; True slots use rectangular coordinates + (r #:init-value 0 #:accessor real-part #:init-keyword #:r) + (i #:init-value 0 #:accessor imag-part #:init-keyword #:i) + ;; Virtual slots access do the conversion + (m #:accessor magnitude #:init-keyword #:magn + #:allocation #:virtual + #:slot-ref (lambda (o) + (let ((r (slot-ref o 'r)) (i (slot-ref o 'i))) + (sqrt (+ (* r r) (* i i))))) + #:slot-set! (lambda (o m) + (let ((a (slot-ref o 'a))) + (slot-set! o 'r (* m (cos a))) + (slot-set! o 'i (* m (sin a)))))) + (a #:accessor angle #:init-keyword #:angle + #:allocation #:virtual + #:slot-ref (lambda (o) + (atan (slot-ref o 'i) (slot-ref o 'r))) + #:slot-set! (lambda(o a) + (let ((m (slot-ref o 'm))) + (slot-set! o 'r (* m (cos a))) + (slot-set! o 'i (* m (sin a))))))) + +@end lisp +@center @emph{Fig 2: A @code{<complex>} number class definition using virtual slots} +@end group +@end example + +@sp 3 +This class definition implements two real slots (@code{r} and +@code{i}). Values of the @code{m} and @code{a} virtual slots are +calculated from real slot values. Reading a virtual slot leads to the +application of the function defined in the @code{#:slot-ref} +option. Writing such a slot leads to the application of the function +defined in the @code{#:slot-set!} option. For instance, the following +expression + +@findex #:slot-set! +@findex #:slot-ref +@lisp +(slot-set! c 'a 3) +@end lisp + +permits to set the angle of the @code{c} complex number. This expression +conducts, in fact, to the evaluation of the following expression + +@lisp +((lambda o m) + (let ((m (slot-ref o 'm))) + (slot-set! o 'r (* m (cos a))) + (slot-set! o 'i (* m (sin a)))) + c 3) +@end lisp + +A more complete example is given below: + +@example +@group +@lisp +(define c (make <complex> #:r 12 #:i 20)) +(real-part c) @result{} 12 +(angle c) @result{} 1.03037682652431 +(slot-set! c 'i 10) +(set! (real-part c) 1) +(describe c) @result{} + #<<complex> 401e9b58> is an instance of class <complex> + Slots are: + r = 1 + i = 10 + m = 10.0498756211209 + a = 1.47112767430373 +@end lisp +@end group +@end example + +Since initialization keywords have been defined for the four slots, we +can now define the @code{make-rectangular} and @code{make-polar} standard +Scheme primitives. + +@lisp +(define make-rectangular + (lambda (x y) (make <complex> #:r x #:i y))) + +(define make-polar + (lambda (x y) (make <complex> #:magn x #:angle y))) +@end lisp + +@node Class precedence list, , Slot description, Inheritance +@subsection Class precedence list + +A class may have more than one superclass. @footnote{This section is an +adaptation of Jeff Dalton's (J.Dalton@@ed.ac.uk) @cite{Brief +introduction to CLOS}} With single inheritance (one superclass), it is +easy to order the super classes from most to least specific. This is the +rule: + +@display +@cartouche +Rule 1: Each class is more specific than its superclasses.@c was \bf +@end cartouche +@end display + +With multiple inheritance, ordering is harder. Suppose we have + +@lisp +(define-class X () + (x #:init-value 1)) + +(define-class Y () + (x #:init-value 2)) + +(define-class Z (X Y) + (@dots{})) +@end lisp + +In this case, the @code{Z} class is more specific than the @code{X} or +@code{Y} class for instances of @code{Z}. However, the @code{#:init-value} +specified in @code{X} and @code{Y} leads to a problem: which one +overrides the other? The rule in @goops{}, as in CLOS, is that the +superclasses listed earlier are more specific than those listed later. +So: + +@display +@cartouche +Rule 2: For a given class, superclasses listed earlier are more + specific than those listed later. +@end cartouche +@end display + +These rules are used to compute a linear order for a class and all its +superclasses, from most specific to least specific. This order is +called the ``class precedence list'' of the class. Given these two +rules, we can claim that the initial form for the @code{x} slot of +previous example is 1 since the class @code{X} is placed before @code{Y} +in class precedence list of @code{Z}. + +These two rules are not always enough to determine a unique order, +however, but they give an idea of how things work. Taking the @code{F} +class shown in Figure@ 1, the class precedence list is + +@example +(f d e a c b <object> <top>) +@end example + +However, it is usually considered a bad idea for programmers to rely on +exactly what the order is. If the order for some superclasses is important, +it can be expressed directly in the class definition. + +The precedence list of a class can be obtained by the function +@code{class-precedence-list}. This function returns a ordered +list whose first element is the most specific class. For instance, + +@lisp +(class-precedence-list B) @result{} (#<<class> B 401b97c8> + #<<class> <object> 401e4a10> + #<<class> <top> 4026a9d8>) +@end lisp + +However, this result is not too much readable; using the function +@code{class-name} yields a clearer result: + +@lisp +(map class-name (class-precedence-list B)) @result{} (B <object> <top>) +@end lisp + +@node Generic functions, , Inheritance, Tutorial +@section Generic functions + +@menu +* Generic functions and methods:: +* Next-method:: +* Example:: +@end menu + +@node Generic functions and methods, Next-method, Generic functions, Generic functions +@subsection Generic functions and methods + +@c \label{gf-n-methods} +Neither @goops{} nor CLOS use the message mechanism for methods as most +Object Oriented language do. Instead, they use the notion of +@dfn{generic functions}. A generic function can be seen as a methods +``tanker''. When the evaluator requested the application of a generic +function, all the methods of this generic function will be grabbed and +the most specific among them will be applied. We say that a method +@var{M} is @emph{more specific} than a method @var{M'} if the class of +its parameters are more specific than the @var{M'} ones. To be more +precise, when a generic function must be ``called'' the system will: + +@cindex generic function +@enumerate +@item +search among all the generic function those which are applicable +@item +sort the list of applicable methods in the ``most specific'' order +@item +call the most specific method of this list (i.e. the first method of +the sorted methods list). +@end enumerate + +The definition of a generic function is done with the +@code{define-generic} macro. Definition of a new method is done with the +@code{define-method} macro. Note that @code{define-method} automatically +defines the generic function if it has not been defined +before. Consequently, most of the time, the @code{define-generic} needs +not be used. +@findex define-generic +@findex define-method +Consider the following definitions: + +@lisp +(define-generic G) +(define-method (G (a <integer>) b) 'integer) +(define-method (G (a <real>) b) 'real) +(define-method (G a b) 'top) +@end lisp + +The @code{define-generic} call defines @var{G} as a generic +function. Note that the signature of the generic function is not given +upon definition, contrarily to CLOS. This will permit methods with +different signatures for a given generic function, as we shall see +later. The three next lines define methods for the @var{G} generic +function. Each method uses a sequence of @dfn{parameter specializers} +that specify when the given method is applicable. A specializer permits +to indicate the class a parameter must belong to (directly or +indirectly) to be applicable. If no specializer is given, the system +defaults it to @code{<top>}. Thus, the first method definition is +equivalent to + +@cindex parameter specializers +@lisp +(define-method (G (a <integer>) (b <top>)) 'integer) +@end lisp + +Now, let us look at some possible calls to generic function @var{G}: + +@lisp +(G 2 3) @result{} integer +(G 2 #t) @result{} integer +(G 1.2 'a) @result{} real +@c (G #3 'a) @result{} real @c was {\sharpsign} +(G #t #f) @result{} top +(G 1 2 3) @result{} error (since no method exists for 3 parameters) +@end lisp + +The preceding methods use only one specializer per parameter list. Of +course, each parameter can use a specializer. In this case, the +parameter list is scanned from left to right to determine the +applicability of a method. Suppose we declare now + +@lisp +(define-method (G (a <integer>) (b <number>)) 'integer-number) +(define-method (G (a <integer>) (b <real>)) 'integer-real) +(define-method (G (a <integer>) (b <integer>)) 'integer-integer) +(define-method (G a (b <number>)) 'top-number) +@end lisp + +In this case, + +@lisp +(G 1 2) @result{} integer-integer +(G 1 1.0) @result{} integer-real +(G 1 #t) @result{} integer +(G 'a 1) @result{} top-number +@end lisp + +@node Next-method, Example, Generic functions and methods, Generic functions +@subsection Next-method + +When a generic function is called, the list of applicable methods is +built. As mentioned before, the most specific method of this list is +applied (see@ @ref{Generic functions and methods}). This method may call +the next method in the list of applicable methods. This is done by using +the special form @code{next-method}. Consider the following definitions + +@lisp +(define-method (Test (a <integer>)) (cons 'integer (next-method))) +(define-method (Test (a <number>)) (cons 'number (next-method))) +(define-method (Test a) (list 'top)) +@end lisp + +With those definitions, + +@lisp +(Test 1) @result{} (integer number top) +(Test 1.0) @result{} (number top) +(Test #t) @result{} (top) +@end lisp + +@node Example, , Next-method, Generic functions +@subsection Example + +In this section we shall continue to define operations on the @code{<complex>} +class defined in Figure@ 2. Suppose that we want to use it to implement +complex numbers completely. For instance a definition for the addition of +two complexes could be + +@lisp +(define-method (new-+ (a <complex>) (b <complex>)) + (make-rectangular (+ (real-part a) (real-part b)) + (+ (imag-part a) (imag-part b)))) +@end lisp + +To be sure that the @code{+} used in the method @code{new-+} is the standard +addition we can do: + +@lisp +(define-generic new-+) + +(let ((+ +)) + (define-method (new-+ (a <complex>) (b <complex>)) + (make-rectangular (+ (real-part a) (real-part b)) + (+ (imag-part a) (imag-part b))))) +@end lisp + +The @code{define-generic} ensures here that @code{new-+} will be defined +in the global environment. Once this is done, we can add methods to the +generic function @code{new-+} which make a closure on the @code{+} +symbol. A complete writing of the @code{new-+} methods is shown in +Figure@ 3. + +@example +@group +@lisp +(define-generic new-+) + +(let ((+ +)) + + (define-method (new-+ (a <real>) (b <real>)) (+ a b)) + + (define-method (new-+ (a <real>) (b <complex>)) + (make-rectangular (+ a (real-part b)) (imag-part b))) + + (define-method (new-+ (a <complex>) (b <real>)) + (make-rectangular (+ (real-part a) b) (imag-part a))) + + (define-method (new-+ (a <complex>) (b <complex>)) + (make-rectangular (+ (real-part a) (real-part b)) + (+ (imag-part a) (imag-part b)))) + + (define-method (new-+ (a <number>)) a) + + (define-method (new-+) 0) + + (define-method (new-+ . args) + (new-+ (car args) + (apply new-+ (cdr args))))) + +(set! + new-+) +@end lisp + +@center @emph{Fig 3: Extending @code{+} for dealing with complex numbers} +@end group +@end example + +@sp 3 +We use here the fact that generic function are not obliged to have the +same number of parameters, contrarily to CLOS. The four first methods +implement the dyadic addition. The fifth method says that the addition +of a single element is this element itself. The sixth method says that +using the addition with no parameter always return 0. The last method +takes an arbitrary number of parameters@footnote{The parameter list for +a @code{define-method} follows the conventions used for Scheme +procedures. In particular it can use the dot notation or a symbol to +denote an arbitrary number of parameters}. This method acts as a kind +of @code{reduce}: it calls the dyadic addition on the @emph{car} of the +list and on the result of applying it on its rest. To finish, the +@code{set!} permits to redefine the @code{+} symbol to our extended +addition. + +@sp 3 +To terminate our implementation (integration?) of complex numbers, we can +redefine standard Scheme predicates in the following manner: + +@lisp +(define-method (complex? c <complex>) #t) +(define-method (complex? c) #f) + +(define-method (number? n <number>) #t) +(define-method (number? n) #f) +@dots{} +@dots{} +@end lisp + +Standard primitives in which complex numbers are involved could also be +redefined in the same manner. + diff --git a/doc/goops/goops.texi b/doc/goops/goops.texi new file mode 100644 index 000000000..ac08a2625 --- /dev/null +++ b/doc/goops/goops.texi @@ -0,0 +1,2788 @@ +\input texinfo +@c -*-texinfo-*- +@c %**start of header +@setfilename goops.info +@settitle Goops Manual +@set goops +@setchapternewpage odd +@paragraphindent 0 +@c %**end of header + +@set VERSION 0.3 + +@dircategory The Algorithmic Language Scheme +@direntry +* GOOPS: (goops). The GOOPS reference manual. +@end direntry + +@macro goops +GOOPS +@end macro + +@macro guile +Guile +@end macro + +@ifinfo +This file documents GOOPS, an object oriented extension for Guile. + +Copyright (C) 1999, 2000, 2001 Free Software Foundation + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@end ifinfo + +@c This title page illustrates only one of the +@c two methods of forming a title page. + +@titlepage +@title Goops Manual +@subtitle For use with GOOPS @value{VERSION} +@include AUTHORS + +@c The following two commands +@c start the copyright page. +@page +@vskip 0pt plus 1filll +Copyright @copyright{} 1999 Free Software Foundation + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@end titlepage + +@node Top, Introduction, (dir), (dir) + +@menu +[When the manual is completed, this will be a flat index in the style of + the Emacs manual. More nodes will turn up under parts I-III.] + +Part I: Preliminaries + +* Introduction:: +* Getting Started:: + +Part II: Reference Manual + +* Reference Manual:: + +Part III: GOOPS Meta Object Protocol + +* MOP Specification:: + +The GOOPS tutorial + +* Tutorial:: + +* Index:: +* Concept Index:: +* Function and Variable Index:: +@end menu + +@iftex +@chapter Preliminaries +@end iftex + +@node Introduction, Getting Started, Top, Top +@section Introduction + +@goops{} is the object oriented extension to @guile{}. Its +implementation is derived from @w{STk-3.99.3} by Erick Gallesio and +version 1.3 of Gregor Kiczales @cite{Tiny-Clos}. It is very close in +spirit to CLOS, the Common Lisp Object System (@cite{CLtL2}) but is +adapted for the Scheme language. While GOOPS is not compatible with any +of these systems, GOOPS contains a compatibility module which allows for +execution of STKlos programs. + +Briefly stated, the @goops{} extension gives the user a full object +oriented system with multiple inheritance and generic functions with +multi-method dispatch. Furthermore, the implementation relies on a true +meta object protocol, in the spirit of the one defined for CLOS +(@cite{Gregor Kiczales: A Metaobject Protocol}). + +@node Getting Started, Reference Manual, Introduction, Top +@section Getting Started + +@menu +* Running GOOPS:: + +Examples of some basic GOOPS functionality. + +* Methods:: +* User-defined types:: +* Asking for the type of an object:: + +See further in the GOOPS tutorial available in this distribution in +info (goops.info) and texinfo format. +@end menu + +@node Running GOOPS, Methods, Getting Started, Getting Started +@subsection Running GOOPS + +@enumerate +@item +Type + +@smalllisp +guile-oops +@end smalllisp + +You should now be at the Guile prompt ("guile> "). + +@item +Type + +@smalllisp +(use-modules (oop goops)) +@end smalllisp + +to load GOOPS. (If your system supports dynamic loading, you +should be able to do this not only from `guile-oops' but from an +arbitrary Guile interpreter.) +@end enumerate + +We're now ready to try some basic GOOPS functionality. + +@node Methods, User-defined types, Running GOOPS, Getting Started +@subsection Methods + +@smalllisp +@group +(define-method (+ (x <string>) (y <string>)) + (string-append x y)) + +(+ 1 2) --> 3 +(+ "abc" "de") --> "abcde" +@end group +@end smalllisp + +@node User-defined types, Asking for the type of an object, Methods, Getting Started +@subsection User-defined types + +@smalllisp +(define-class <2D-vector> () + (x #:init-value 0 #:accessor x-component #:init-keyword #:x) + (y #:init-value 0 #:accessor y-component #:init-keyword #:y)) + +@group +(use-modules (ice-9 format)) + +(define-method (write (obj <2D-vector>) port) + (display (format #f "<~S, ~S>" (x-component obj) (y-component obj)) + port)) + +(define v (make <2D-vector> #:x 3 #:y 4)) + +v --> <3, 4> +@end group + +@group +(define-method (+ (x <2D-vector>) (y <2D-vector>)) + (make <2D-vector> + #:x (+ (x-component x) (x-component y)) + #:y (+ (y-component x) (y-component y)))) + +(+ v v) --> <6, 8> +@end group +@end smalllisp + +@node Asking for the type of an object, , User-defined types, Getting Started +@subsection Types + +@example +(class-of v) --> #<<class> <2D-vector> 40241ac0> +<2D-vector> --> #<<class> <2D-vector> 40241ac0> +(class-of 1) --> #<<class> <integer> 401b2a98> +<integer> --> #<<class> <integer> 401b2a98> + +(is-a? v <2D-vector>) --> #t +@end example + +@node Reference Manual, MOP Specification, Getting Started, Top +@chapter Reference Manual + +This chapter is the GOOPS reference manual. It aims to describe all the +syntax, procedures, options and associated concepts that a typical +application author would need to understand in order to use GOOPS +effectively in their application. It also describes what is meant by +the GOOPS ``metaobject protocol'' (aka ``MOP''), and indicates how +authors can use the metaobject protocol to customize the behaviour of +GOOPS itself. + +For a detailed specification of the GOOPS metaobject protocol, see +@ref{MOP Specification}. + +@menu +* Introductory Remarks:: +* Defining New Classes:: +* Creating Instances:: +* Accessing Slots:: +* Creating Generic Functions:: +* Adding Methods to Generic Functions:: +* Invoking Generic Functions:: +* Redefining a Class:: +* Changing the Class of an Instance:: +* Introspection:: +* Miscellaneous Functions:: +@end menu + +@node Introductory Remarks +@section Introductory Remarks + +GOOPS is an object-oriented programming system based on a ``metaobject +protocol'' derived from the ones used in CLOS (the Common Lisp Object +System), tiny-clos (a small Scheme implementation of a subset of CLOS +functionality) and STKlos. + +GOOPS can be used by application authors at a basic level without any +need to understand what the metaobject protocol (aka ``MOP'') is and how +it works. On the other hand, the MOP underlies even the customizations +that application authors are likely to make use of very quickly --- such +as defining an @code{initialize} method to customize the initialization +of instances of an application-defined class --- and an understanding of +the MOP makes it much easier to explain such customizations in a precise +way. And in the long run, understanding the MOP is the key both to +understanding GOOPS at a deeper level and to taking full advantage of +GOOPS' power, by customizing the behaviour of GOOPS itself. + +Each of the following sections of the reference manual is arranged +such that the most basic usage is introduced first, and then subsequent +subsections discuss the related internal functions and metaobject +protocols, finishing with a description of how to customize that area of +functionality. + +These introductory remarks continue with a few words about metaobjects +and the MOP. Readers who do not want to be bothered yet with the MOP +and customization could safely skip this subsection on a first reading, +and should correspondingly skip subsequent subsections that are +concerned with internals and customization. + +In general, this reference manual assumes familiarity with standard +object oriented concepts and terminology. However, some of the terms +used in GOOPS is less well known, so the Terminology subsection +provides definitions for these terms. + +@menu +* Metaobjects and the Metaobject Protocol:: +* Terminology:: +@end menu + +@node Metaobjects and the Metaobject Protocol +@subsection Metaobjects and the Metaobject Protocol + +The conceptual building blocks of GOOPS are classes, slot definitions, +instances, generic functions and methods. A class is a grouping of +inheritance relations and slot definitions. An instance is an object +with slots that are allocated following the rules implied by its class's +superclasses and slot definitions. A generic function is a collection +of methods and rules for determining which of those methods to apply +when the generic function is invoked. A method is a procedure and a set +of specializers that specify the type of arguments to which the +procedure is applicable. + +Of these entities, GOOPS represents classes, generic functions and +methods as ``metaobjects''. In other words, the values in a GOOPS +program that describe classes, generic functions and methods, are +themselves instances (or ``objects'') of special GOOPS classes that +encapsulate the behaviour, respectively, of classes, generic functions, +and methods. + +(The other two entities are slot definitions and instances. Slot +definitions are not strictly instances, but every slot definition is +associated with a GOOPS class that specifies the behaviour of the slot +as regards accessibility and protection from garbage collection. +Instances are of course objects in the usual sense, and there is no +benefit from thinking of them as metaobjects.) + +The ``metaobject protocol'' (aka ``MOP'') is the specification of the +generic functions which determine the behaviour of these metaobjects and +the circumstances in which these generic functions are invoked. + +For a concrete example of what this means, consider how GOOPS calculates +the set of slots for a class that is being defined using +@code{define-class}. The desired set of slots is the union of the new +class's direct slots and the slots of all its superclasses. But +@code{define-class} itself does not perform this calculation. Instead, +there is a method of the @code{initialize} generic function that is +specialized for instances of type @code{<class>}, and it is this method +that performs the slot calculation. + +@code{initialize} is a generic function which GOOPS calls whenever a new +instance is created, immediately after allocating memory for a new +instance, in order to initialize the new instance's slots. The sequence +of steps is as follows. + +@itemize @bullet +@item +@code{define-class} uses @code{make} to make a new instance of the +@code{<class>}, passing as initialization arguments the superclasses, +slot definitions and class options that were specified in the +@code{define-class} form. + +@item +@code{make} allocates memory for the new instance, and then invokes the +@code{initialize} generic function to initialize the new instance's +slots. + +@item +The @code{initialize} generic function applies the method that is +specialized for instances of type @code{<class>}, and this method +performs the slot calculation. +@end itemize + +In other words, rather than being hardcoded in @code{define-class}, the +behaviour of class definition is encapsulated by generic function +methods that are specialized for the class @code{<class>}. + +It is possible to create a new class that inherits from @code{<class>}, +which is called a ``metaclass'', and to write a new @code{initialize} +method that is specialized for instances of the new metaclass. Then, if +the @code{define-class} form includes a @code{#:metaclass} class option +whose value is the new metaclass, the class that is defined by the +@code{define-class} form will be an instance of the new metaclass rather +than of the default @code{<class>}, and will be defined in accordance +with the new @code{initialize} method. Thus the default slot +calculation, as well as any other aspect of the new class's relationship +with its superclasses, can be modified or overridden. + +In a similar way, the behaviour of generic functions can be modified or +overridden by creating a new class that inherits from the standard +generic function class @code{<generic>}, writing appropriate methods +that are specialized to the new class, and creating new generic +functions that are instances of the new class. + +The same is true for method metaobjects. And the same basic mechanism +allows the application class author to write an @code{initialize} method +that is specialized to their application class, to initialize instances +of that class. + +Such is the power of the MOP. Note that @code{initialize} is just one +of a large number of generic functions that can be customized to modify +the behaviour of application objects and classes and of GOOPS itself. +Each subsequent section of the reference manual covers a particular area +of GOOPS functionality, and describes the generic functions that are +relevant for customization of that area. + +We conclude this subsection by emphasizing a point that may seem +obvious, but contrasts with the corresponding situation in some other +MOP implementations, such as CLOS. The point is simply that an +identifier which represents a GOOPS class or generic function is a +variable with a first-class value, the value being an instance of class +@code{<class>} or @code{<generic>}. (In CLOS, on the other hand, a +class identifier is a symbol that indexes the corresponding class +metaobject in a separate namespace for classes.) This is, of course, +simply an extension of the tendency in Scheme to avoid the unnecessary +use of, on the one hand, syntactic forms that require unevaluated +arguments and, on the other, separate identifier namespaces (e.g. for +class names), but it is worth noting that GOOPS conforms fully to this +Schemely principle. + +@node Terminology +@subsection Terminology + +It is assumed that the reader is already familiar with standard object +orientation concepts such as classes, objects/instances, +inheritance/subclassing, generic functions and methods, encapsulation +and polymorphism. + +This section explains some of the less well known concepts and +terminology that GOOPS uses, which are assumed by the following sections +of the reference manual. + +@menu +* Metaclass:: +* Class Precedence List:: +* Accessor:: +@end menu + +@node Metaclass +@subsubsection Metaclass + +A @dfn{metaclass} is the class of an object which represents a GOOPS +class. Put more succinctly, a metaclass is a class's class. + +Most GOOPS classes have the metaclass @code{<class>} and, by default, +any new class that is created using @code{define-class} has the +metaclass @code{<class>}. + +But what does this really mean? To find out, let's look in more detail +at what happens when a new class is created using @code{define-class}: + +@example +(define-class <my-class> (<object>) . slots) +@end example + +GOOPS actually expands the @code{define-class} form to something like +this + +@example +(define <my-class> (class (<object>) . slots)) +@end example + +and thence to + +@example +(define <my-class> + (make <class> #:supers (list <object>) #:slots slots)) +@end example + +In other words, the value of @code{<my-class>} is in fact an instance of +the class @code{<class>} with slot values specifying the superclasses +and slot definitions for the class @code{<my-class>}. (@code{#:supers} +and @code{#:slots} are initialization keywords for the @code{dsupers} +and @code{dslots} slots of the @code{<class>} class.) + +In order to take advantage of the full power of the GOOPS metaobject +protocol (@pxref{MOP Specification}), it is sometimes desirable to +create a new class with a metaclass other than the default +@code{<class>}. This is done by writing: + +@example +(define-class <my-class2> (<object>) + slot @dots{} + #:metaclass <my-metaclass>) +@end example + +GOOPS expands this to something like: + +@example +(define <my-class2> + (make <my-metaclass> #:supers (list <object>) #:slots slots)) +@end example + +In this case, the value of @code{<my-class2>} is an instance of the more +specialized class @code{<my-metaclass>}. Note that +@code{<my-metaclass>} itself must previously have been defined as a +subclass of @code{<class>}. For a full discussion of when and how it is +useful to define new metaclasses, see @ref{MOP Specification}. + +Now let's make an instance of @code{<my-class2>}: + +@example +(define my-object (make <my-class2> ...)) +@end example + +All of the following statements are correct expressions of the +relationships between @code{my-object}, @code{<my-class2>}, +@code{<my-metaclass>} and @code{<class>}. + +@itemize @bullet +@item +@code{my-object} is an instance of the class @code{<my-class2>}. + +@item +@code{<my-class2>} is an instance of the class @code{<my-metaclass>}. + +@item +@code{<my-metaclass>} is an instance of the class @code{<class>}. + +@item +The class of @code{my-object} is @code{<my-class2>}. + +@item +The metaclass of @code{my-object} is @code{<my-metaclass>}. + +@item +The class of @code{<my-class2>} is @code{<my-metaclass>}. + +@item +The metaclass of @code{<my-class2>} is @code{<class>}. + +@item +The class of @code{<my-metaclass>} is @code{<class>}. + +@item +The metaclass of @code{<my-metaclass>} is @code{<class>}. + +@item +@code{<my-class2>} is not a metaclass, since it is does not inherit from +@code{<class>}. + +@item +@code{<my-metaclass>} is a metaclass, since it inherits from +@code{<class>}. +@end itemize + +@node Class Precedence List +@subsubsection Class Precedence List + +The @dfn{class precedence list} of a class is the list of all direct and +indirect superclasses of that class, including the class itself. + +In the absence of multiple inheritance, the class precedence list is +ordered straightforwardly, beginning with the class itself and ending +with @code{<top>}. + +For example, given this inheritance hierarchy: + +@example +(define-class <invertebrate> (<object>) @dots{}) +(define-class <echinoderm> (<invertebrate>) @dots{}) +(define-class <starfish> (<echinoderm>) @dots{}) +@end example + +the class precedence list of <starfish> would be + +@example +(<starfish> <echinoderm> <invertebrate> <object> <top>) +@end example + +With multiple inheritance, the algorithm is a little more complicated. +A full description is provided by the GOOPS Tutorial: see @ref{Class +precedence list}. + +``Class precedence list'' is often abbreviated, in documentation and +Scheme variable names, to @dfn{cpl}. + +@node Accessor +@subsubsection Accessor + +An @dfn{accessor} is a generic function with both reference and setter +methods. + +@example +(define-accessor perimeter) +@end example + +Reference methods for an accessor are defined in the same way as generic +function methods. + +@example +(define-method (perimeter (s <square>)) + (* 4 (side-length s))) +@end example + +Setter methods for an accessor are defined by specifying ``(setter +<accessor-name>)'' as the first parameter of the @code{define-method} +call. + +@example +(define-method ((setter perimeter) (s <square>) (n <number>)) + (set! (side-length s) (/ n 4))) +@end example + +Once an appropriate setter method has been defined in this way, it can +be invoked using the generalized @code{set!} syntax, as in: + +@example +(set! (perimeter s1) 18.3) +@end example + +@node Defining New Classes +@section Defining New Classes + +[ *fixme* Somewhere in this manual there needs to be an introductory +discussion about GOOPS classes, generic functions and methods, covering + +@itemize @bullet +@item +how classes encapsulate related items of data in @dfn{slots} + +@item +why it is that, unlike in C++ and Java, a class does not encapsulate the +methods that act upon the class (at least not in the C++/Java sense) + +@item +how generic functions provide a more general solution that provides for +dispatch on all argument types, and avoids idiosyncracies like C++'s +friend classes + +@item +how encapsulation in the sense of data- and code-hiding, or of +distinguishing interface from implementation, is treated in Guile as an +orthogonal concept to object orientation, and is the responsibility of +the module system. +@end itemize + +Some of this is covered in the Tutorial chapter, in @ref{Generic +functions and methods} - perhaps the best solution would be to expand +the discussion there. ] + +@menu +* Basic Class Definition:: +* Class Options:: +* Slot Options:: +* Class Definition Internals:: +* Customizing Class Definition:: +* STKlos Compatibility:: +@end menu + +@node Basic Class Definition +@subsection Basic Class Definition + +New classes are defined using the @code{define-class} syntax, with +arguments that specify the classes that the new class should inherit +from, the direct slots of the new class, and any required class options. + +@deffn syntax define-class name (super @dots{}) slot-definition @dots{} . options +Define a class called @var{name} that inherits from @var{super}s, with +direct slots defined by @var{slot-definition}s and class options +@var{options}. The newly created class is bound to the variable name +@var{name} in the current environment. + +Each @var{slot-definition} is either a symbol that names the slot or a +list, + +@example +(@var{slot-name-symbol} . @var{slot-options}) +@end example + +where @var{slot-name-symbol} is a symbol and @var{slot-options} is a +list with an even number of elements. The even-numbered elements of +@var{slot-options} (counting from zero) are slot option keywords; the +odd-numbered elements are the corresponding values for those keywords. + +@var{options} is a similarly structured list containing class option +keywords and corresponding values. +@end deffn + +The standard GOOPS class and slot options are described in the following +subsections: see @ref{Class Options} and @ref{Slot Options}. + +Example 1. Define a class that combines two pre-existing classes by +inheritance but adds no new slots. + +@example +(define-class <combined> (<tree> <bicycle>)) +@end example + +Example 2. Define a @code{regular-polygon} class with slots for side +length and number of sides that have default values and can be accessed +via the generic functions @code{side-length} and @code{num-sides}. + +@example +(define-class <regular-polygon> () + (sl #:init-value 1 #:accessor side-length) + (ns #:init-value 5 #:accessor num-sides)) +@end example + +Example 3. Define a class whose behavior (and that of its instances) is +customized via an application-defined metaclass. + +@example +(define-class <tcpip-fsm> () + (s #:init-value #f #:accessor state) + ... + #:metaclass <finite-state-class>) +@end example + +@node Class Options +@subsection Class Options + +@deffn {class option} #:metaclass metaclass +The @code{#:metaclass} class option specifies the metaclass of the class +being defined. @var{metaclass} must be a class that inherits from +@code{<class>}. For an introduction to the use of metaclasses, see +@ref{Metaobjects and the Metaobject Protocol} and @ref{Metaclass}. + +If the @code{#:metaclass} option is absent, GOOPS reuses or constructs a +metaclass for the new class by calling @code{ensure-metaclass} +(@pxref{Class Definition Internals,, ensure-metaclass}). +@end deffn + +@deffn {class option} #:name name +The @code{#:name} class option specifies the new class's name. This +name is used to identify the class whenever related objects - the class +itself, its instances and its subclasses - are printed. + +If the @code{#:name} option is absent, GOOPS uses the first argument to +@code{define-class} as the class name. +@end deffn + +@deffn {class option} #:environment environment +*fixme* Not sure about this one, but I think that the +@code{#:environment} option specifies the environment in which the +class's getters and setters are computed and evaluated. + +If the @code{#:environment} option is not specified, the class's +environment defaults to the top-level environment in which the +@code{define-class} form appears. +@end deffn + +@node Slot Options +@subsection Slot Options + +@deffn {slot option} #:allocation allocation +The @code{#:allocation} option tells GOOPS how to allocate storage for +the slot. Possible values for @var{allocation} are + +@itemize @bullet +@item @code{#:instance} + +Indicates that GOOPS should create separate storage for this slot in +each new instance of the containing class (and its subclasses). + +@item @code{#:class} + +Indicates that GOOPS should create storage for this slot that is shared +by all instances of the containing class (and its subclasses). In other +words, a slot in class @var{C} with allocation @code{#:class} is shared +by all @var{instance}s for which @code{(is-a? @var{instance} @var{c})}. + +@item @code{#:each-subclass} + +Indicates that GOOPS should create storage for this slot that is shared +by all @emph{direct} instances of the containing class, and that +whenever a subclass of the containing class is defined, GOOPS should +create a new storage for the slot that is shared by all @emph{direct} +instances of the subclass. In other words, a slot with allocation +@code{#:each-subclass} is shared by all instances with the same +@code{class-of}. + +@item @code{#:virtual} + +Indicates that GOOPS should not allocate storage for this slot. The +slot definition must also include the @code{#:slot-ref} and +@code{#:slot-set!} options to specify how to reference and set the value +for this slot. +@end itemize + +The default value is @code{#:instance}. + +Slot allocation options are processed when defining a new class by the +generic function @code{compute-get-n-set}, which is specialized by the +class's metaclass. Hence new types of slot allocation can be +implemented by defining a new metaclass and a method for +@code{compute-get-n-set} that is specialized for the new metaclass. For +an example of how to do this, see @ref{Customizing Class Definition}. +@end deffn + +@deffn {slot option} #:slot-ref getter +@deffnx {slot option} #:slot-set! setter +The @code{#:slot-ref} and @code{#:slot-set!} options must be specified +if the slot allocation is @code{#:virtual}, and are ignored otherwise. + +@var{getter} should be a closure taking a single @var{instance} parameter +that returns the current slot value. @var{setter} should be a closure +taking two parameters - @var{instance} and @var{new-val} - that sets the +slot value to @var{new-val}. +@end deffn + +@deffn {slot option} #:getter getter +@deffnx {slot option} #:setter setter +@deffnx {slot option} #:accessor accessor +These options, if present, tell GOOPS to create generic function and +method definitions that can be used to get and set the slot value more +conveniently than by using @code{slot-ref} and @code{slot-set!}. + +@var{getter} specifies a generic function to which GOOPS will add a +method for getting the slot value. @var{setter} specifies a generic +function to which GOOPS will add a method for setting the slot value. +@var{accessor} specifies an accessor to which GOOPS will add methods for +both getting and setting the slot value. + +So if a class includes a slot definition like this: + +@example +(c #:getter get-count #:setter set-count #:accessor count) +@end example + +GOOPS defines generic function methods such that the slot value can be +referenced using either the getter or the accessor - + +@example +(let ((current-count (get-count obj))) @dots{}) +(let ((current-count (count obj))) @dots{}) +@end example + +- and set using either the setter or the accessor - + +@example +(set-count obj (+ 1 current-count)) +(set! (count obj) (+ 1 current-count)) +@end example + +Note that + +@itemize @bullet +@item +with an accessor, the slot value is set using the generalized +@code{set!} syntax + +@item +in practice, it is unusual for a slot to use all three of these options: +read-only, write-only and read-write slots would typically use only +@code{#:getter}, @code{#:setter} and @code{#:accessor} options +respectively. +@end itemize + +If the specified names are already bound in the top-level environment to +values that cannot be upgraded to generic functions, those values are +overwritten during evaluation of the @code{define-class} that contains +the slot definition. For details, see @ref{Generic Function Internals,, +ensure-generic}. +@end deffn + +@deffn {slot option} #:init-value init-value +@deffnx {slot option} #:init-form init-form +@deffnx {slot option} #:init-thunk init-thunk +@deffnx {slot option} #:init-keyword init-keyword +These options provide various ways to specify how to initialize the +slot's value at instance creation time. @var{init-value} is a fixed +value. @var{init-thunk} is a procedure of no arguments that is called +when a new instance is created and should return the desired initial +slot value. @var{init-form} is an unevaluated expression that gets +evaluated when a new instance is created and should return the desired +initial slot value. @var{init-keyword} is a keyword that can be used to +pass an initial slot value to @code{make} when creating a new instance. + +If more than one of these options is specified for the same slot, the +order of precedence, highest first is + +@itemize @bullet +@item +@code{#:init-keyword}, if @var{init-keyword} is present in the options +passed to @code{make} + +@item +@code{#:init-thunk}, @code{#:init-form} or @code{#:init-value}. +@end itemize + +If the slot definition contains more than one initialization option of +the same precedence, the later ones are ignored. If a slot is not +initialized at all, its value is unbound. + +In general, slots that are shared between more than one instance are +only initialized at new instance creation time if the slot value is +unbound at that time. However, if the new instance creation specifies +a valid init keyword and value for a shared slot, the slot is +re-initialized regardless of its previous value. + +Note, however, that the power of GOOPS' metaobject protocol means that +everything written here may be customized or overridden for particular +classes! The slot initializations described here are performed by the least +specialized method of the generic function @code{initialize}, whose +signature is + +@example +(define-method (initialize (object <object>) initargs) ...) +@end example + +The initialization of instances of any given class can be customized by +defining a @code{initialize} method that is specialized for that class, +and the author of the specialized method may decide to call +@code{next-method} - which will result in a call to the next less +specialized @code{initialize} method - at any point within the +specialized code, or maybe not at all. In general, therefore, the +initialization mechanisms described here may be modified or overridden by +more specialized code, or may not be supported at all for particular +classes. +@end deffn + +@node Class Definition Internals +@subsection Class Definition Internals + +Implementation notes: @code{define-class} expands to an expression which + +@itemize @bullet +@item +checks that it is being evaluated only at top level + +@item +defines any accessors that are implied by the @var{slot-definition}s + +@item +uses @code{class} to create the new class (@pxref{Class Definition +Internals,, class}) + +@item +checks for a previous class definition for @var{name} and, if found, +handles the redefinition by invoking @code{class-redefinition} +(@pxref{Redefining a Class}). +@end itemize + +@deffn syntax class name (super @dots{}) slot-definition @dots{} . options +Return a newly created class that inherits from @var{super}s, with +direct slots defined by @var{slot-definition}s and class options +@var{options}. For the format of @var{slot-definition}s and +@var{options}, see @ref{Basic Class Definition,, define-class}. +@end deffn + +Implementation notes: @code{class} expands to an expression which + +@itemize @bullet +@item +processes the class and slot definition options to check that they are +well-formed, to convert the @code{#:init-form} option to an +@code{#:init-thunk} option, to supply a default environment parameter +(the current top-level environment) and to evaluate all the bits that +need to be evaluated + +@item +calls @code{make-class} to create the class with the processed and +evaluated parameters. +@end itemize + +@deffn procedure make-class supers slots . options +Return a newly created class that inherits from @var{supers}, with +direct slots defined by @var{slots} and class options @var{options}. +For the format of @var{slots} and @var{options}, see @ref{Basic Class +Definition,, define-class}, except note that for @code{make-class}, +@var{slots} and @var{options} are separate list parameters: @var{slots} +here is a list of slot definitions. +@end deffn + +Implementation notes: @code{make-class} + +@itemize @bullet +@item +adds @code{<object>} to the @var{supers} list if @var{supers} is empty +or if none of the classes in @var{supers} have @code{<object>} in their +class precedence list + +@item +defaults the @code{#:environment}, @code{#:name} and @code{#:metaclass} +options, if they are not specified by @var{options}, to the current +top-level environment, the unbound value, and @code{(ensure-metaclass +@var{supers})} respectively (@pxref{Class Definition Internals,, +ensure-metaclass}) + +@item +checks for duplicate classes in @var{supers} and duplicate slot names in +@var{slots}, and signals an error if there are any duplicates + +@item +calls @code{make}, passing the metaclass as the first parameter and all +other parameters as option keywords with values. +@end itemize + +@deffn procedure ensure-metaclass supers env +Return a metaclass suitable for a class that inherits from the list of +classes in @var{supers}. The returned metaclass is the union by +inheritance of the metaclasses of the classes in @var{supers}. + +In the simplest case, where all the @var{supers} are straightforward +classes with metaclass @code{<class>}, the returned metaclass is just +@code{<class>}. + +For a more complex example, suppose that @var{supers} contained one +class with metaclass @code{<operator-class>} and one with metaclass +@code{<foreign-object-class>}. Then the returned metaclass would be a +class that inherits from both @code{<operator-class>} and +@code{<foreign-object-class>}. + +If @var{supers} is the empty list, @code{ensure-metaclass} returns the +default GOOPS metaclass @code{<class>}. + +GOOPS keeps a list of the metaclasses created by +@code{ensure-metaclass}, so that each required type of metaclass only +has to be created once. + +The @code{env} parameter is ignored. +@end deffn + +@deffn procedure ensure-metaclass-with-supers meta-supers +@code{ensure-metaclass-with-supers} is an internal procedure used by +@code{ensure-metaclass} (@pxref{Class Definition Internals,, +ensure-metaclass}). It returns a metaclass that is the union by +inheritance of the metaclasses in @var{meta-supers}. +@end deffn + +The internals of @code{make}, which is ultimately used to create the new +class object, are described in @ref{Customizing Instance Creation}, +which covers the creation and initialization of instances in general. + +@node Customizing Class Definition +@subsection Customizing Class Definition + +During the initialization of a new class, GOOPS calls a number of generic +functions with the newly allocated class instance as the first +argument. Specifically, GOOPS calls the generic function + +@itemize @bullet +@item +(initialize @var{class} @dots{}) +@end itemize + +where @var{class} is the newly allocated class instance, and the default +@code{initialize} method for arguments of type @code{<class>} calls the +generic functions + +@itemize @bullet +@item +(compute-cpl @var{class}) + +@item +(compute-slots @var{class}) + +@item +(compute-get-n-set @var{class} @var{slot-def}), for each of the slot +definitions returned by @code{compute-slots} + +@item +(compute-getter-method @var{class} @var{slot-def}), for each of the +slot definitions returned by @code{compute-slots} that includes a +@code{#:getter} or @code{#:accessor} slot option + +@item +(compute-setter-method @var{class} @var{slot-def}), for each of the +slot definitions returned by @code{compute-slots} that includes a +@code{#:setter} or @code{#:accessor} slot option. +@end itemize + +If the metaclass of the new class is something more specialized than the +default @code{<class>}, then the type of @var{class} in the calls above +is more specialized than @code{<class>}, and hence it becomes possible +to define generic function methods, specialized for the new class's +metaclass, that can modify or override the default behaviour of +@code{initialize}, @code{compute-cpl} or @code{compute-get-n-set}. + +@code{compute-cpl} computes the class precedence list (``CPL'') for the +new class (@pxref{Class precedence list}), and returns it as a list of +class objects. The CPL is important because it defines a superclass +ordering that is used, when a generic function is invoked upon an +instance of the class, to decide which of the available generic function +methods is the most specific. Hence @code{compute-cpl} could be +customized in order to modify the CPL ordering algorithm for all classes +with a special metaclass. + +The default CPL algorithm is encapsulated by the @code{compute-std-cpl} +procedure, which is in turn called by the default @code{compute-cpl} +method. + +@deffn procedure compute-std-cpl class +Compute and return the class precedence list for @var{class} according +to the algorithm described in @ref{Class precedence list}. +@end deffn + +@code{compute-slots} computes and returns a list of all slot definitions +for the new class. By default, this list includes the direct slot +definitions from the @code{define-class} form, plus the slot definitions +that are inherited from the new class's superclasses. The default +@code{compute-slots} method uses the CPL computed by @code{compute-cpl} +to calculate this union of slot definitions, with the rule that slots +inherited from superclasses are shadowed by direct slots with the same +name. One possible reason for customizing @code{compute-slots} would be +to implement an alternative resolution strategy for slot name conflicts. + +@code{compute-get-n-set} computes the low-level closures that will be +used to get and set the value of a particular slot, and returns them in +a list with two elements. + +The closures returned depend on how storage for that slot is allocated. +The standard @code{compute-get-n-set} method, specialized for classes of +type @code{<class>}, handles the standard GOOPS values for the +@code{#:allocation} slot option (@pxref{Slot Options,, allocation}). By +defining a new @code{compute-get-n-set} method for a more specialized +metaclass, it is possible to support new types of slot allocation. + +Suppose you wanted to create a large number of instances of some class +with a slot that should be shared between some but not all instances of +that class - say every 10 instances should share the same slot storage. +The following example shows how to implement and use a new type of slot +allocation to do this. + +@example +(define-class <batched-allocation-metaclass> (<class>)) + +(let ((batch-allocation-count 0) + (batch-get-n-set #f)) + (define-method (compute-get-n-set (class <batched-allocation-metaclass>) s) + (case (slot-definition-allocation s) + ((#:batched) + ;; If we've already used the same slot storage for 10 instances, + ;; reset variables. + (if (= batch-allocation-count 10) + (begin + (set! batch-allocation-count 0) + (set! batch-get-n-set #f))) + ;; If we don't have a current pair of get and set closures, + ;; create one. make-closure-variable returns a pair of closures + ;; around a single Scheme variable - see goops.scm for details. + (or batch-get-n-set + (set! batch-get-n-set (make-closure-variable))) + ;; Increment the batch allocation count. + (set! batch-allocation-count (+ batch-allocation-count 1)) + batch-get-n-set) + + ;; Call next-method to handle standard allocation types. + (else (next-method))))) + +(define-class <class-using-batched-slot> () + ... + (c #:allocation #:batched) + ... + #:metaclass <batched-allocation-metaclass>) +@end example + +The usage of @code{compute-getter-method} and @code{compute-setter-method} +is described in @ref{MOP Specification}. + +@code{compute-cpl} and @code{compute-get-n-set} are called by the +standard @code{initialize} method for classes whose metaclass is +@code{<class>}. But @code{initialize} itself can also be modified, by +defining an @code{initialize} method specialized to the new class's +metaclass. Such a method could complete override the standard +behaviour, by not calling @code{(next-method)} at all, but more +typically it would perform additional class initialization steps before +and/or after calling @code{(next-method)} for the standard behaviour. + +@node STKlos Compatibility +@subsection STKlos Compatibility + +If the STKlos compatibility module is loaded, @code{define-class} is +overwritten by a STKlos-specific definition; the standard GOOPS +definition of @code{define-class} remains available in +@code{standard-define-class}. + +@deffn syntax standard-define-class name (super @dots{}) slot-definition @dots{} . options +@code{standard-define-class} is equivalent to the standard GOOPS +@code{define-class}. +@end deffn + +@node Creating Instances +@section Creating Instances + +@menu +* Basic Instance Creation:: +* Customizing Instance Creation:: +@end menu + +@node Basic Instance Creation +@subsection Basic Instance Creation + +To create a new instance of any GOOPS class, use the generic function +@code{make} or @code{make-instance}, passing the required class and any +appropriate instance initialization arguments as keyword and value +pairs. Note that @code{make} and @code{make-instances} are aliases for +each other - their behaviour is identical. + +@deffn generic make +@deffnx method make (class <class>) . initargs +Create and return a new instance of class @var{class}, initialized using +@var{initargs}. + +In theory, @var{initargs} can have any structure that is understood by +whatever methods get applied when the @code{initialize} generic function +is applied to the newly allocated instance. + +In practice, specialized @code{initialize} methods would normally call +@code{(next-method)}, and so eventually the standard GOOPS +@code{initialize} methods are applied. These methods expect +@var{initargs} to be a list with an even number of elements, where +even-numbered elements (counting from zero) are keywords and +odd-numbered elements are the corresponding values. + +GOOPS processes initialization argument keywords automatically for slots +whose definition includes the @code{#:init-keyword} option (@pxref{Slot +Options,, init-keyword}). Other keyword value pairs can only be +processed by an @code{initialize} method that is specialized for the new +instance's class. Any unprocessed keyword value pairs are ignored. +@end deffn + +@deffn generic make-instance +@deffnx method make-instance (class <class>) . initargs +@code{make-instance} is an alias for @code{make}. +@end deffn + +@node Customizing Instance Creation +@subsection Customizing Instance Creation + +@code{make} itself is a generic function. Hence the @code{make} +invocation itself can be customized in the case where the new instance's +metaclass is more specialized than the default @code{<class>}, by +defining a @code{make} method that is specialized to that metaclass. + +Normally, however, the method for classes with metaclass @code{<class>} +will be applied. This method calls two generic functions: + +@itemize @bullet +@item +(allocate-instance @var{class} . @var{initargs}) + +@item +(initialize @var{instance} . @var{initargs}) +@end itemize + +@code{allocate-instance} allocates storage for and returns the new +instance, uninitialized. You might customize @code{allocate-instance}, +for example, if you wanted to provide a GOOPS wrapper around some other +object programming system. + +To do this, you would create a specialized metaclass, which would act as +the metaclass for all classes and instances from the other system. Then +define an @code{allocate-instance} method, specialized to that +metaclass, which calls a Guile primitive C function, which in turn +allocates the new instance using the interface of the other object +system. + +In this case, for a complete system, you would also need to customize a +number of other generic functions like @code{make} and +@code{initialize}, so that GOOPS knows how to make classes from the +other system, access instance slots, and so on. + +@code{initialize} initializes the instance that is returned by +@code{allocate-instance}. The standard GOOPS methods perform +initializations appropriate to the instance class. + +@itemize @bullet +@item +At the least specialized level, the method for instances of type +@code{<object>} performs internal GOOPS instance initialization, and +initializes the instance's slots according to the slot definitions and +any slot initialization keywords that appear in @var{initargs}. + +@item +The method for instances of type @code{<class>} calls +@code{(next-method)}, then performs the class initializations described +in @ref{Customizing Class Definition}. + +@item +and so on for generic functions, method, operator classes @dots{} +@end itemize + +Similarly, you can customize the initialization of instances of any +application-defined class by defining an @code{initialize} method +specialized to that class. + +Imagine a class whose instances' slots need to be initialized at +instance creation time by querying a database. Although it might be +possible to achieve this a combination of @code{#:init-thunk} keywords +and closures in the slot definitions, it is neater to write an +@code{initialize} method for the class that queries the database once +and initializes all the dependent slot values according to the results. + +@node Accessing Slots +@section Accessing Slots + +The definition of a slot contains at the very least a slot name, and may +also contain various slot options, including getter, setter and/or +accessor functions for the slot. + +It is always possible to access slots by name, using the various +``slot-ref'' and ``slot-set!'' procedures described in the following +subsections. For example, + +@example +(define-class <my-class> () ;; Define a class with slots + (count #:init-value 0) ;; named "count" and "cache". + (cache #:init-value '()) + @dots{}) + +(define inst (make <my-class>)) ;; Make an instance of this class. + +(slot-set! inst 'count 5) ;; Set the value of the "count" + ;; slot to 5. + +(slot-set! inst 'cache ;; Modify the value of the + (cons (cons "^it" "It") ;; "cache" slot. + (slot-ref inst 'cache))) +@end example + +If a slot definition includes a getter, setter or accessor function, +these can be used instead of @code{slot-ref} and @code{slot-set!} to +access the slot. + +@example +(define-class <adv-class> () ;; Define a new class whose slots + (count #:setter set-count) ;; use a getter, a setter and + (cache #:accessor cache) ;; an accessor. + (csize #:getter cache-size) + @dots{}) + +(define inst (make <adv-class>)) ;; Make an instance of this class. + +(set-count inst 5) ;; Set the value of the "count" + ;; slot to 5. + +(set! (cache inst) ;; Modify the value of the + (cons (cons "^it" "It") ;; "cache" slot. + (cache inst))) + +(let ((size (cache-size inst))) ;; Get the value of the "csize" + @dots{}) ;; slot. +@end example + +Whichever of these methods is used to access slots, GOOPS always calls +the low-level @dfn{getter} and @dfn{setter} closures for the slot to get +and set its value. These closures make sure that the slot behaves +according to the @code{#:allocation} type that was specified in the slot +definition (@pxref{Slot Options,, allocation}). (For more about these +closures, see @ref{Customizing Class Definition,, compute-get-n-set}.) + +@menu +* Instance Slots:: +* Class Slots:: +* Handling Slot Access Errors:: +@end menu + +@node Instance Slots +@subsection Instance Slots + +Any slot, regardless of its allocation, can be queried, referenced and +set using the following four primitive procedures. + +@deffn {primitive procedure} slot-exists? obj slot-name +Return @code{#t} if @var{obj} has a slot with name @var{slot-name}, +otherwise @code{#f}. +@end deffn + +@deffn {primitive procedure} slot-bound? obj slot-name +Return @code{#t} if the slot named @var{slot-name} in @var{obj} has a +value, otherwise @code{#f}. + +@code{slot-bound?} calls the generic function @code{slot-missing} if +@var{obj} does not have a slot called @var{slot-name} (@pxref{Handling +Slot Access Errors, slot-missing}). +@end deffn + +@deffn {primitive procedure} slot-ref obj slot-name +Return the value of the slot named @var{slot-name} in @var{obj}. + +@code{slot-ref} calls the generic function @code{slot-missing} if +@var{obj} does not have a slot called @var{slot-name} (@pxref{Handling +Slot Access Errors, slot-missing}). + +@code{slot-ref} calls the generic function @code{slot-unbound} if the +named slot in @var{obj} does not have a value (@pxref{Handling Slot +Access Errors, slot-unbound}). +@end deffn + +@deffn {primitive procedure} slot-set! obj slot-name value +Set the value of the slot named @var{slot-name} in @var{obj} to @var{value}. + +@code{slot-set!} calls the generic function @code{slot-missing} if +@var{obj} does not have a slot called @var{slot-name} (@pxref{Handling +Slot Access Errors, slot-missing}). +@end deffn + +GOOPS stores information about slots in class metaobjects. Internally, +all of these procedures work by looking up the slot definition for the +slot named @var{slot-name} in the class metaobject for @code{(class-of +@var{obj})}, and then using the slot definition's ``getter'' and +``setter'' closures to get and set the slot value. + +The next four procedures differ from the previous ones in that they take +the class metaobject as an explicit argument, rather than assuming +@code{(class-of @var{obj})}. Therefore they allow you to apply the +``getter'' and ``setter'' closures of a slot definition in one class to +an instance of a different class. + +[ *fixme* I have no idea why this is useful! Perhaps when a slot in +@code{(class-of @var{obj})} shadows a slot with the same name in one of +its superclasses? There should be an enlightening example here. ] + +@deffn {primitive procedure} slot-exists-using-class? class obj slot-name +Return @code{#t} if the class metaobject @var{class} has a slot +definition for a slot with name @var{slot-name}, otherwise @code{#f}. +@end deffn + +@deffn {primitive procedure} slot-bound-using-class? class obj slot-name +Return @code{#t} if applying @code{slot-ref-using-class} to the same +arguments would call the generic function @code{slot-unbound}, otherwise +@code{#f}. + +@code{slot-bound-using-class?} calls the generic function +@code{slot-missing} if @var{class} does not have a slot definition for a +slot called @var{slot-name} (@pxref{Handling Slot Access Errors, +slot-missing}). +@end deffn + +@deffn {primitive procedure} slot-ref-using-class class obj slot-name +Apply the ``getter'' closure for the slot named @var{slot-name} in +@var{class} to @var{obj}, and return its result. + +@code{slot-ref-using-class} calls the generic function +@code{slot-missing} if @var{class} does not have a slot definition for a +slot called @var{slot-name} (@pxref{Handling Slot Access Errors, +slot-missing}). + +@code{slot-ref-using-class} calls the generic function +@code{slot-unbound} if the application of the ``getter'' closure to +@var{obj} returns an unbound value (@pxref{Handling Slot Access Errors, +slot-unbound}). +@end deffn + +@deffn {primitive procedure} slot-set-using-class! class obj slot-name value +Apply the ``setter'' closure for the slot named @var{slot-name} in +@var{class} to @var{obj} and @var{value}. + +@code{slot-set-using-class!} calls the generic function +@code{slot-missing} if @var{class} does not have a slot definition for a +slot called @var{slot-name} (@pxref{Handling Slot Access Errors, +slot-missing}). +@end deffn + +@node Class Slots +@subsection Class Slots + +Slots whose allocation is per-class rather than per-instance can be +referenced and set without needing to specify any particular instance. + +@deffn procedure class-slot-ref class slot-name +Return the value of the slot named @var{slot-name} in class @var{class}. +The named slot must have @code{#:class} or @code{#:each-subclass} +allocation (@pxref{Slot Options,, allocation}). + +If there is no such slot with @code{#:class} or @code{#:each-subclass} +allocation, @code{class-slot-ref} calls the @code{slot-missing} generic +function with arguments @var{class} and @var{slot-name}. Otherwise, if +the slot value is unbound, @code{class-slot-ref} calls the +@code{slot-missing} generic function, with the same arguments. +@end deffn + +@deffn procedure class-slot-set! class slot-name value +Set the value of the slot named @var{slot-name} in class @var{class} to +@var{value}. The named slot must have @code{#:class} or +@code{#:each-subclass} allocation (@pxref{Slot Options,, allocation}). + +If there is no such slot with @code{#:class} or @code{#:each-subclass} +allocation, @code{class-slot-ref} calls the @code{slot-missing} generic +function with arguments @var{class} and @var{slot-name}. +@end deffn + +@node Handling Slot Access Errors +@subsection Handling Slot Access Errors + +GOOPS calls one of the following generic functions when a ``slot-ref'' +or ``slot-set!'' call specifies a non-existent slot name, or tries to +reference a slot whose value is unbound. + +@deffn generic slot-missing +@deffnx method slot-missing (class <class>) slot-name +@deffnx method slot-missing (class <class>) (object <object>) slot-name +@deffnx method slot-missing (class <class>) (object <object>) slot-name value +When an application attempts to reference or set a class or instance +slot by name, and the slot name is invalid for the specified @var{class} +or @var{object}, GOOPS calls the @code{slot-missing} generic function. + +The default methods all call @code{goops-error} with an appropriate +message. +@end deffn + +@deffn generic slot-unbound +@deffnx method slot-unbound (object <object>) +@deffnx method slot-unbound (class <class>) slot-name +@deffnx method slot-unbound (class <class>) (object <object>) slot-name +When an application attempts to reference a class or instance slot, and +the slot's value is unbound, GOOPS calls the @code{slot-unbound} generic +function. + +The default methods all call @code{goops-error} with an appropriate +message. +@end deffn + +@node Creating Generic Functions +@section Creating Generic Functions + +A generic function is a collection of methods, with rules for +determining which of the methods should be applied for any given +invocation of the generic function. + +GOOPS represents generic functions as metaobjects of the class +@code{<generic>} (or one of its subclasses). + +@menu +* Basic Generic Function Creation:: +* Generic Function Internals:: +* Extending Guiles Primitives:: +@end menu + +@node Basic Generic Function Creation +@subsection Basic Generic Function Creation + +The following forms may be used to bind a variable to a generic +function. Depending on that variable's pre-existing value, the generic +function may be created empty - with no methods - or it may contain +methods that are inferred from the pre-existing value. + +It is not, in general, necessary to use @code{define-generic} or +@code{define-accessor} before defining methods for the generic function +using @code{define-method}, since @code{define-method} will +automatically interpolate a @code{define-generic} call, or upgrade an +existing generic to an accessor, if that is implied by the +@code{define-method} call. Note in particular that, +if the specified variable already has a @emph{generic function} value, +@code{define-generic} and @code{define-accessor} will @emph{discard} it! +Obviously it is application-dependent whether this is desirable or not. + +If, for example, you wanted to extend @code{+} for a class representing +a new numerical type, you probably want to inherit any existing methods +for @code{+} and so should not use @code{define-generic}. If, on the +other hand, you do not want to risk inheriting methods whose behaviour +might surprise you, you can use @code{define-generic} or +@code{define-accessor} to wipe the slate clean. + +@deffn syntax define-generic symbol +Create a generic function with name @var{symbol} and bind it to the +variable @var{symbol}. + +If the variable @var{symbol} was previously bound to a Scheme procedure +(or procedure-with-setter), the old procedure (and setter) is +incorporated into the new generic function as its default procedure (and +setter). Any other previous value that was bound to @var{symbol}, +including an existing generic function, is overwritten by the new +generic function. +@end deffn + +@deffn syntax define-accessor symbol +Create an accessor with name @var{symbol} and bind it to the variable +@var{symbol}. + +If the variable @var{symbol} was previously bound to a Scheme procedure +(or procedure-with-setter), the old procedure (and setter) is +incorporated into the new accessor as its default procedure (and +setter). Any other previous value that was bound to @var{symbol}, +including an existing generic function or accessor, is overwritten by +the new definition. +@end deffn + +@node Generic Function Internals +@subsection Generic Function Internals + +@code{define-generic} calls @code{ensure-generic} to upgrade a +pre-existing procedure value, or @code{make} with metaclass +@code{<generic>} to create a new generic function. + +@code{define-accessor} calls @code{ensure-accessor} to upgrade a +pre-existing procedure value, or @code{make-accessor} to create a new +accessor. + +@deffn procedure ensure-generic old-definition [name] +Return a generic function with name @var{name}, if possible by using or +upgrading @var{old-definition}. If unspecified, @var{name} defaults to +@code{#f}. + +If @var{old-definition} is already a generic function, it is returned +unchanged. + +If @var{old-definition} is a Scheme procedure or procedure-with-setter, +@code{ensure-generic} returns a new generic function that uses +@var{old-definition} for its default procedure and setter. + +Otherwise @code{ensure-generic} returns a new generic function with no +defaults and no methods. +@end deffn + +@deffn procedure make-generic [name] +Return a new generic function with name @code{(car @var{name})}. If +unspecified, @var{name} defaults to @code{#f}. +@end deffn + +@code{ensure-generic} calls @code{make} with metaclasses +@code{<generic>} and @code{<generic-with-setter>}, depending on the +previous value of the variable that it is trying to upgrade. + +@code{make-generic} is a simple wrapper for @code{make} with metaclass +@code{<generic>}. + +@deffn procedure ensure-accessor proc [name] +Return an accessor with name @var{name}, if possible by using or +upgrading @var{proc}. If unspecified, @var{name} defaults to @code{#f}. + +If @var{proc} is already an accessor, it is returned unchanged. + +If @var{proc} is a Scheme procedure, procedure-with-setter or generic +function, @code{ensure-accessor} returns an accessor that reuses the +reusable elements of @var{proc}. + +Otherwise @code{ensure-accessor} returns a new accessor with no defaults +and no methods. +@end deffn + +@deffn procedure make-accessor [name] +Return a new accessor with name @code{(car @var{name})}. If +unspecified, @var{name} defaults to @code{#f}. +@end deffn + +@code{ensure-accessor} calls @code{make} with +metaclass @code{<generic-with-setter>}, as well as calls to +@code{ensure-generic}, @code{make-accessor} and (tail recursively) +@code{ensure-accessor}. + +@code{make-accessor} calls @code{make} twice, first +with metaclass @code{<generic>} to create a generic function for the +setter, then with metaclass @code{<generic-with-setter>} to create the +accessor, passing the setter generic function as the value of the +@code{#:setter} keyword. + +@node Extending Guiles Primitives +@subsection Extending Guile's Primitives + +When GOOPS is loaded, many of Guile's primitive procedures can be +extended by giving them a generic function definition that operates +in conjunction with their normal C-coded implementation. For +primitives that are extended in this way, the result from the user- +or application-level point of view is that the extended primitive +behaves exactly like a generic function with the C-coded implementation +as its default method. + +The @code{generic-capability?} predicate should be used to determine +whether a particular primitive is extensible in this way. + +@deffn {primitive procedure} generic-capability? primitive +Return @code{#t} if @var{primitive} can be extended by giving it a +generic function definition, otherwise @code{#f}. +@end deffn + +Even when a primitive procedure is extensible like this, its generic +function definition is not created until it is needed by a call to +@code{define-method}, or until the application explicitly requests it +by calling @code{enable-primitive-generic!}. + +@deffn {primitive procedure} enable-primitive-generic! primitive +Force the creation of a generic function definition for +@var{primitive}. +@end deffn + +Once the generic function definition for a primitive has been created, +it can be retrieved using @code{primitive-generic-generic}. + +@deffn {primitive procedure} primitive-generic-generic primitive +Return the generic function definition of @var{primitive}. + +@code{primitive-generic-generic} raises an error if @var{primitive} +is not a primitive with generic capability, or if its generic capability +has not yet been enabled, whether implicitly (by @code{define-method}) +or explicitly (by @code{enable-primitive-generic!}). +@end deffn + +Note that the distinction between, on the one hand, primitives with +additional generic function definitions and, on the other hand, generic +functions with a default method, may disappear when GOOPS is fully +integrated into the core of Guile. Consequently, the +procedures described in this section may disappear as well. + +@node Adding Methods to Generic Functions +@section Adding Methods to Generic Functions + +@menu +* Basic Method Definition:: +* Method Definition Internals:: +@end menu + +@node Basic Method Definition +@subsection Basic Method Definition + +To add a method to a generic function, use the @code{define-method} form. + +@deffn syntax define-method (generic parameter @dots{}) . body +Define a method for the generic function or accessor @var{generic} with +parameters @var{parameter}s and body @var{body}. + +@var{generic} is a generic function. If @var{generic} is a variable +which is not yet bound to a generic function object, the expansion of +@code{define-method} will include a call to @code{define-generic}. If +@var{generic} is @code{(setter @var{generic-with-setter})}, where +@var{generic-with-setter} is a variable which is not yet bound to a +generic-with-setter object, the expansion will include a call to +@code{define-accessor}. + +Each @var{parameter} must be either a symbol or a two-element list +@code{(@var{symbol} @var{class})}. The symbols refer to variables in +the @var{body} that will be bound to the parameters supplied by the +caller when calling this method. The @var{class}es, if present, +specify the possible combinations of parameters to which this method +can be applied. + +@var{body} is the body of the method definition. +@end deffn + +@code{define-method} expressions look a little like normal Scheme +procedure definitions of the form + +@example +(define (name formals @dots{}) . body) +@end example + +The most important difference is that each formal parameter, apart from the +possible ``rest'' argument, can be qualified by a class name: +@code{@var{formal}} becomes @code{(@var{formal} @var{class})}. The +meaning of this qualification is that the method being defined +will only be applicable in a particular generic function invocation if +the corresponding argument is an instance of @code{@var{class}} (or one of +its subclasses). If more than one of the formal parameters is qualified +in this way, then the method will only be applicable if each of the +corresponding arguments is an instance of its respective qualifying class. + +Note that unqualified formal parameters act as though they are qualified +by the class @code{<top>}, which GOOPS uses to mean the superclass of +all valid Scheme types, including both primitive types and GOOPS classes. + +For example, if a generic function method is defined with +@var{parameter}s @code{((s1 <square>) (n <number>))}, that method is +only applicable to invocations of its generic function that have two +parameters where the first parameter is an instance of the +@code{<square>} class and the second parameter is a number. + +If a generic function is invoked with a combination of parameters for which +there is no applicable method, GOOPS raises an error. For more about +invocation error handling, and generic function invocation in general, +see @ref{Invoking Generic Functions}. + +@node Method Definition Internals +@subsection Method Definition Internals + +@code{define-method} + +@itemize @bullet +@item +checks the form of the first parameter, and applies the following steps +to the accessor's setter if it has the @code{(setter @dots{})} form + +@item +interpolates a call to @code{define-generic} or @code{define-accessor} +if a generic function is not already defined with the supplied name + +@item +calls @code{method} with the @var{parameter}s and @var{body}, to make a +new method instance + +@item +calls @code{add-method!} to add this method to the relevant generic +function. +@end itemize + +@deffn syntax method (parameter @dots{}) . body +Make a method whose specializers are defined by the classes in +@var{parameter}s and whose procedure definition is constructed from the +@var{parameter} symbols and @var{body} forms. + +The @var{parameter} and @var{body} parameters should be as for +@code{define-method} (@pxref{Basic Method Definition,, define-method}). +@end deffn + +@code{method} + +@itemize @bullet +@item +extracts formals and specializing classes from the @var{parameter}s, +defaulting the class for unspecialized parameters to @code{<top>} + +@item +creates a closure using the formals and the @var{body} forms + +@item +calls @code{make} with metaclass @code{<method>} and the specializers +and closure using the @code{#:specializers} and @code{#:procedure} +keywords. +@end itemize + +@deffn procedure make-method specializers procedure +Make a method using @var{specializers} and @var{procedure}. + +@var{specializers} should be a list of classes that specifies the +parameter combinations to which this method will be applicable. + +@var{procedure} should be the closure that will applied to the generic +function parameters when this method is invoked. +@end deffn + +@code{make-method} is a simple wrapper around @code{make} with metaclass +@code{<method>}. + +@deffn generic add-method! target method +Generic function for adding method @var{method} to @var{target}. +@end deffn + +@deffn method add-method! (generic <generic>) (method <method>) +Add method @var{method} to the generic function @var{generic}. +@end deffn + +@deffn method add-method! (proc <procedure>) (method <method>) +If @var{proc} is a procedure with generic capability (@pxref{Extending +Guiles Primitives,, generic-capability?}), upgrade it to a +primitive generic and add @var{method} to its generic function +definition. +@end deffn + +@deffn method add-method! (pg <primitive-generic>) (method <method>) +Add method @var{method} to the generic function definition of @var{pg}. + +Implementation: @code{(add-method! (primitive-generic-generic pg) method)}. +@end deffn + +@deffn method add-method! (whatever <top>) (method <method>) +Raise an error indicating that @var{whatever} is not a valid generic +function. +@end deffn + +@node Invoking Generic Functions +@section Invoking Generic Functions + +When a variable with a generic function definition appears as the first +element of a list that is being evaluated, the Guile evaluator tries +to apply the generic function to the arguments obtained by evaluating +the remaining elements of the list. [ *fixme* How do I put this in a +more Schemely and less Lispy way? ] + +Usually a generic function contains several method definitions, with +varying degrees of formal parameter specialization (@pxref{Basic +Method Definition,, define-method}). So it is necessary to sort these +methods by specificity with respect to the supplied arguments, and then +apply the most specific method definition. Less specific methods +may be applied subsequently if a method that is being applied calls +@code{next-method}. + +@menu +* Determining Which Methods to Apply:: +* Handling Invocation Errors:: +@end menu + +@node Determining Which Methods to Apply +@subsection Determining Which Methods to Apply + +[ *fixme* Sorry - this is the area of GOOPS that I understand least of +all, so I'm afraid I have to pass on this section. Would some other +kind person consider filling it in? ] + +@deffn generic apply-generic +@deffnx method apply-generic (gf <generic>) args +@end deffn + +@deffn generic compute-applicable-methods +@deffnx method compute-applicable-methods (gf <generic>) args +@end deffn + +@deffn generic sort-applicable-methods +@deffnx method sort-applicable-methods (gf <generic>) methods args +@end deffn + +@deffn generic method-more-specific? +@deffnx method method-more-specific? (m1 <method>) (m2 <method>) args +@end deffn + +@deffn generic apply-method +@deffnx method apply-method (gf <generic>) methods build-next args +@end deffn + +@deffn generic apply-methods +@deffnx method apply-methods (gf <generic>) (l <list>) args +@end deffn + +@node Handling Invocation Errors +@subsection Handling Invocation Errors + +@deffn generic no-method +@deffnx method no-method (gf <generic>) args +When an application invokes a generic function, and no methods at all +have been defined for that generic function, GOOPS calls the +@code{no-method} generic function. The default method calls +@code{goops-error} with an appropriate message. +@end deffn + +@deffn generic no-applicable-method +@deffnx method no-applicable-method (gf <generic>) args +When an application applies a generic function to a set of arguments, +and no methods have been defined for those argument types, GOOPS calls +the @code{no-applicable-method} generic function. The default method +calls @code{goops-error} with an appropriate message. +@end deffn + +@deffn generic no-next-method +@deffnx method no-next-method (gf <generic>) args +When a generic function method calls @code{(next-method)} to invoke the +next less specialized method for that generic function, and no less +specialized methods have been defined for the current generic function +arguments, GOOPS calls the @code{no-next-method} generic function. The +default method calls @code{goops-error} with an appropriate message. +@end deffn + +@node Redefining a Class +@section Redefining a Class + +Suppose that a class @code{<my-class>} is defined using @code{define-class} +(@pxref{Basic Class Definition,, define-class}), with slots that have +accessor functions, and that an application has created several instances +of @code{<my-class>} using @code{make} (@pxref{Basic Instance Creation,, +make}). What then happens if @code{<my-class>} is redefined by calling +@code{define-class} again? + +@menu +* Default Class Redefinition Behaviour:: +* Customizing Class Redefinition:: +@end menu + +@node Default Class Redefinition Behaviour +@subsection Default Class Redefinition Behaviour + +GOOPS' default answer to this question is as follows. + +@itemize @bullet +@item +All existing direct instances of @code{<my-class>} are converted to be +instances of the new class. This is achieved by preserving the values +of slots that exist in both the old and new definitions, and initializing the +values of new slots in the usual way (@pxref{Basic Instance Creation,, +make}). + +@item +All existing subclasses of @code{<my-class>} are redefined, as though +the @code{define-class} expressions that defined them were re-evaluated +following the redefinition of @code{<my-class>}, and the class +redefinition process described here is applied recursively to the +redefined subclasses. + +@item +Once all of its instances and subclasses have been updated, the class +metaobject previously bound to the variable @code{<my-class>} is no +longer needed and so can be allowed to be garbage collected. +@end itemize + +To keep things tidy, GOOPS also needs to do a little housekeeping on +methods that are associated with the redefined class. + +@itemize @bullet +@item +Slot accessor methods for slots in the old definition should be removed +from their generic functions. They will be replaced by accessor methods +for the slots of the new class definition. + +@item +Any generic function method that uses the old @code{<my-class>} metaobject +as one of its formal parameter specializers must be updated to refer to +the new @code{<my-class>} metaobject. (Whenever a new generic function +method is defined, @code{define-method} adds the method to a list stored +in the class metaobject for each class used as a formal parameter +specializer, so it is easy to identify all the methods that must be +updated when a class is redefined.) +@end itemize + +If this class redefinition strategy strikes you as rather counter-intuitive, +bear in mind that it is derived from similar behaviour in other object +systems such as CLOS, and that experience in those systems has shown it to be +very useful in practice. + +Also bear in mind that, like most of GOOPS' default behaviour, it can +be customized@dots{} + +@node Customizing Class Redefinition +@subsection Customizing Class Redefinition + +When @code{define-class} notices that a class is being redefined, +it constructs the new class metaobject as usual, and then invokes the +@code{class-redefinition} generic function with the old and new classes +as arguments. Therefore, if the old or new classes have metaclasses +other than the default @code{<class>}, class redefinition behaviour can +be customized by defining a @code{class-redefinition} method that is +specialized for the relevant metaclasses. + +@deffn generic class-redefinition +Handle the class redefinition from @var{old-class} to @var{new-class}, +and return the new class metaobject that should be bound to the +variable specified by @code{define-class}'s first argument. +@end deffn + +@deffn method class-redefinition (old-class <class>) (new-class <class>) +Implements GOOPS' default class redefinition behaviour, as described in +@ref{Default Class Redefinition Behaviour}. Returns the metaobject +for the new class definition. +@end deffn + +An alternative class redefinition strategy could be to leave all +existing instances as instances of the old class, but accepting that the +old class is now ``nameless'', since its name has been taken over by the +new definition. In this strategy, any existing subclasses could also +be left as they are, on the understanding that they inherit from a nameless +superclass. + +This strategy is easily implemented in GOOPS, by defining a new metaclass, +that will be used as the metaclass for all classes to which the strategy +should apply, and then defining a @code{class-redefinition} method that +is specialized for this metaclass: + +@example +(define-class <can-be-nameless> (<class>)) + +(define-method (class-redefinition (old <can-be-nameless>) (new <class>)) + new) +@end example + +When customization can be as easy as this, aren't you glad that GOOPS +implements the far more difficult strategy as its default! + +Finally, note that, if @code{class-redefinition} itself is not customized, +the default @code{class-redefinition} method invokes three further +generic functions that could be individually customized: + +@itemize @bullet +@item +(remove-class-accessors! @var{old-class}) + +@item +(update-direct-method! @var{method} @var{old-class} @var{new-class}) + +@item +(update-direct-subclass! @var{subclass} @var{old-class} @var{new-class}) +@end itemize + +and the default methods for these generic functions invoke further +generic functions, and so on@dots{} The detailed protocol for all of these +is described in @ref{MOP Specification}. + +@node Changing the Class of an Instance +@section Changing the Class of an Instance + +You can change the class of an existing instance by invoking the +generic function @code{change-class} with two arguments: the instance +and the new class. + +@deffn generic change-class +@end deffn + +The default method for @code{change-class} decides how to implement the +change of class by looking at the slot definitions for the instance's +existing class and for the new class. If the new class has slots with +the same name as slots in the existing class, the values for those slots +are preserved. Slots that are present only in the existing class are +discarded. Slots that are present only in the new class are initialized +using the corresponding slot definition's init function (@pxref{Classes,, +slot-init-function}). + +@deffn {method} change-class (obj <object>) (new <class>) +Modify instance @var{obj} to make it an instance of class @var{new}. + +The value of each of @var{obj}'s slots is preserved only if a similarly named +slot exists in @var{new}; any other slot values are discarded. + +The slots in @var{new} that do not correspond to any of @var{obj}'s +pre-existing slots are initialized according to @var{new}'s slot definitions' +init functions. +@end deffn + +Customized change of class behaviour can be implemented by defining +@code{change-class} methods that are specialized either by the class +of the instances to be modified or by the metaclass of the new class. + +When a class is redefined (@pxref{Redefining a Class}), and the default +class redefinition behaviour is not overridden, GOOPS (eventually) +invokes the @code{change-class} generic function for each existing +instance of the redefined class. + +@node Introspection +@section Introspection + +@dfn{Introspection}, also known as @dfn{reflection}, is the name given +to the ability to obtain information dynamically about GOOPS metaobjects. +It is perhaps best illustrated by considering an object oriented language +that does not provide any introspection, namely C++. + +Nothing in C++ allows a running program to obtain answers to the following +types of question: + +@itemize @bullet +@item +What are the data members of this object or class? + +@item +What classes does this class inherit from? + +@item +Is this method call virtual or non-virtual? + +@item +If I invoke @code{Employee::adjustHoliday()}, what class contains the +@code{adjustHoliday()} method that will be applied? +@end itemize + +In C++, answers to such questions can only be determined by looking at +the source code, if you have access to it. GOOPS, on the other hand, +includes procedures that allow answers to these questions --- or their +GOOPS equivalents --- to be obtained dynamically, at run time. + +@menu +* Classes:: +* Slots:: +* Instances:: +* Generic Functions:: +* Generic Function Methods:: +@end menu + +@node Classes +@subsection Classes + +@deffn {primitive procedure} class-name class +Return the name of class @var{class}. +This is the value of the @var{class} metaobject's @code{name} slot. +@end deffn + +@deffn {primitive procedure} class-direct-supers class +Return a list containing the direct superclasses of @var{class}. +This is the value of the @var{class} metaobject's +@code{direct-supers} slot. +@end deffn + +@deffn {primitive procedure} class-direct-slots class +Return a list containing the slot definitions of the direct slots of +@var{class}. +This is the value of the @var{class} metaobject's @code{direct-slots} +slot. +@end deffn + +@deffn {primitive procedure} class-direct-subclasses class +Return a list containing the direct subclasses of @var{class}. +This is the value of the @var{class} metaobject's +@code{direct-subclasses} slot. +@end deffn + +@deffn {primitive procedure} class-direct-methods class +Return a list of all the generic function methods that use @var{class} +as a formal parameter specializer. +This is the value of the @var{class} metaobject's @code{direct-methods} +slot. +@end deffn + +@deffn {primitive procedure} class-precedence-list class +Return the class precedence list for class @var{class} (@pxref{Class +precedence list}). +This is the value of the @var{class} metaobject's @code{cpl} slot. +@end deffn + +@deffn {primitive procedure} class-slots class +Return a list containing the slot definitions for all @var{class}'s slots, +including any slots that are inherited from superclasses. +This is the value of the @var{class} metaobject's @code{slots} slot. +@end deffn + +@deffn {primitive procedure} class-environment class +Return the value of @var{class}'s @code{environment} slot. +[ *fixme* I don't know what this value is used for. ] +@end deffn + +@deffn procedure class-subclasses class +Return a list of all subclasses of @var{class}. +@end deffn + +@deffn procedure class-methods class +Return a list of all methods that use @var{class} or a subclass of +@var{class} as one of its formal parameter specializers. +@end deffn + +@node Slots +@subsection Slots + +@deffn procedure class-slot-definition class slot-name +Return the slot definition for the slot named @var{slot-name} in class +@var{class}. @var{slot-name} should be a symbol. +@end deffn + +@deffn procedure slot-definition-name slot-def +Extract and return the slot name from @var{slot-def}. +@end deffn + +@deffn procedure slot-definition-options slot-def +Extract and return the slot options from @var{slot-def}. +@end deffn + +@deffn procedure slot-definition-allocation slot-def +Extract and return the slot allocation option from @var{slot-def}. This +is the value of the @code{#:allocation} keyword (@pxref{Slot Options,, +allocation}), or @code{#:instance} if the @code{#:allocation} keyword is +absent. +@end deffn + +@deffn procedure slot-definition-getter slot-def +Extract and return the slot getter option from @var{slot-def}. This is +the value of the @code{#:getter} keyword (@pxref{Slot Options,, +getter}), or @code{#f} if the @code{#:getter} keyword is absent. +@end deffn + +@deffn procedure slot-definition-setter slot-def +Extract and return the slot setter option from @var{slot-def}. This is +the value of the @code{#:setter} keyword (@pxref{Slot Options,, +setter}), or @code{#f} if the @code{#:setter} keyword is absent. +@end deffn + +@deffn procedure slot-definition-accessor slot-def +Extract and return the slot accessor option from @var{slot-def}. This +is the value of the @code{#:accessor} keyword (@pxref{Slot Options,, +accessor}), or @code{#f} if the @code{#:accessor} keyword is absent. +@end deffn + +@deffn procedure slot-definition-init-value slot-def +Extract and return the slot init-value option from @var{slot-def}. This +is the value of the @code{#:init-value} keyword (@pxref{Slot Options,, +init-value}), or the unbound value if the @code{#:init-value} keyword is +absent. +@end deffn + +@deffn procedure slot-definition-init-form slot-def +Extract and return the slot init-form option from @var{slot-def}. This +is the value of the @code{#:init-form} keyword (@pxref{Slot Options,, +init-form}), or the unbound value if the @code{#:init-form} keyword is +absent. +@end deffn + +@deffn procedure slot-definition-init-thunk slot-def +Extract and return the slot init-thunk option from @var{slot-def}. This +is the value of the @code{#:init-thunk} keyword (@pxref{Slot Options,, +init-thunk}), or @code{#f} if the @code{#:init-thunk} keyword is absent. +@end deffn + +@deffn procedure slot-definition-init-keyword slot-def +Extract and return the slot init-keyword option from @var{slot-def}. +This is the value of the @code{#:init-keyword} keyword (@pxref{Slot +Options,, init-keyword}), or @code{#f} if the @code{#:init-keyword} +keyword is absent. +@end deffn + +@deffn procedure slot-init-function class slot-name +Return the initialization function for the slot named @var{slot-name} in +class @var{class}. @var{slot-name} should be a symbol. + +The returned initialization function incorporates the effects of the +standard @code{#:init-thunk}, @code{#:init-form} and @code{#:init-value} +slot options. These initializations can be overridden by the +@code{#:init-keyword} slot option or by a specialized @code{initialize} +method, so, in general, the function returned by +@code{slot-init-function} may be irrelevant. For a fuller discussion, +see @ref{Slot Options,, init-value}. +@end deffn + +@node Instances +@subsection Instances + +@deffn {primitive procedure} class-of value +Return the GOOPS class of any Scheme @var{value}. +@end deffn + +@deffn {primitive procedure} instance? object +Return @code{#t} if @var{object} is any GOOPS instance, otherwise +@code{#f}. +@end deffn + +@deffn procedure is-a? object class +Return @code{#t} if @var{object} is an instance of @var{class} or one of +its subclasses. +@end deffn + +Implementation notes: @code{is-a?} uses @code{class-of} and +@code{class-precedence-list} to obtain the class precedence list for +@var{object}. + +@node Generic Functions +@subsection Generic Functions + +@deffn {primitive procedure} generic-function-name gf +Return the name of generic function @var{gf}. +@end deffn + +@deffn {primitive procedure} generic-function-methods gf +Return a list of the methods of generic function @var{gf}. +This is the value of the @var{gf} metaobject's @code{methods} slot. +@end deffn + +@node Generic Function Methods +@subsection Generic Function Methods + +@deffn {primitive procedure} method-generic-function method +Return the generic function that @var{method} belongs to. +This is the value of the @var{method} metaobject's +@code{generic-function} slot. +@end deffn + +@deffn {primitive procedure} method-specializers method +Return a list of @var{method}'s formal parameter specializers . +This is the value of the @var{method} metaobject's +@code{specializers} slot. +@end deffn + +@deffn {primitive procedure} method-procedure method +Return the procedure that implements @var{method}. +This is the value of the @var{method} metaobject's +@code{procedure} slot. +@end deffn + +@deffn generic method-source +@deffnx method method-source (m <method>) +Return an expression that prints to show the definition of method +@var{m}. + +@example +(define-generic cube) + +(define-method (cube (n <number>)) + (* n n n)) + +(map method-source (generic-function-methods cube)) +@result{} +((method ((n <number>)) (* n n n))) +@end example +@end deffn + +@node Miscellaneous Functions +@section Miscellaneous Functions + +@menu +* Administrative Functions:: +* Error Handling:: +* Object Comparisons:: +* Cloning Objects:: +* Write and Display:: +@end menu + +@node Administrative Functions +@subsection Administration Functions + +This section describes administrative, non-technical GOOPS functions. + +@deffn primitive goops-version +Return the current GOOPS version as a string, for example ``0.2''. +@end deffn + +@node Error Handling +@subsection Error Handling + +The procedure @code{goops-error} is called to raise an appropriate error +by the default methods of the following generic functions: + +@itemize @bullet +@item +@code{slot-missing} (@pxref{Handling Slot Access Errors,, slot-missing}) + +@item +@code{slot-unbound} (@pxref{Handling Slot Access Errors,, slot-unbound}) + +@item +@code{no-method} (@pxref{Handling Invocation Errors,, no-method}) + +@item +@code{no-applicable-method} (@pxref{Handling Invocation Errors,, +no-applicable-method}) + +@item +@code{no-next-method} (@pxref{Handling Invocation Errors,, +no-next-method}) +@end itemize + +If you customize these functions for particular classes or metaclasses, +you may still want to use @code{goops-error} to signal any error +conditions that you detect. + +@deffn procedure goops-error format-string . args +Raise an error with key @code{goops-error} and error message constructed +from @var{format-string} and @var{args}. Error message formatting is +as done by @code{scm-error}. +@end deffn + +@node Object Comparisons +@subsection Object Comparisons + +@deffn generic object-eqv? +@deffnx method object-eqv? ((x <top>) (y <top>)) +@deffnx generic object-equal? +@deffnx method object-equal? ((x <top>) (y <top>)) +Generic functions and default (unspecialized) methods for comparing two +GOOPS objects. + +The default methods always return @code{#f}. Application class authors +may wish to define specialized methods for @code{object-eqv?} and +@code{object-equal?} that compare instances of the same class for +equality in whatever sense is useful to the application. +@end deffn + +@node Cloning Objects +@subsection Cloning Objects + +@deffn generic shallow-clone +@deffnx method shallow-clone (self <object>) +Return a ``shallow'' clone of @var{self}. The default method makes a +shallow clone by allocating a new instance and copying slot values from +self to the new instance. Each slot value is copied either as an +immediate value or by reference. +@end deffn + +@deffn generic deep-clone +@deffnx method deep-clone (self <object>) +Return a ``deep'' clone of @var{self}. The default method makes a deep +clone by allocating a new instance and copying or cloning slot values +from self to the new instance. If a slot value is an instance +(satisfies @code{instance?}), it is cloned by calling @code{deep-clone} +on that value. Other slot values are copied either as immediate values +or by reference. +@end deffn + +@node Write and Display +@subsection Write and Display + +@deffn {primitive generic} write object port +@deffnx {primitive generic} display object port +When GOOPS is loaded, @code{write} and @code{display} become generic +functions with special methods for printing + +@itemize @bullet +@item +objects - instances of the class @code{<object>} + +@item +foreign objects - instances of the class @code{<foreign-object>} + +@item +classes - instances of the class @code{<class>} + +@item +generic functions - instances of the class @code{<generic>} + +@item +methods - instances of the class @code{<method>}. +@end itemize + +@code{write} and @code{display} print non-GOOPS values in the same way +as the Guile primitive @code{write} and @code{display} functions. +@end deffn + +@node MOP Specification, Tutorial, Reference Manual, Top +@chapter MOP Specification + +For an introduction to metaobjects and the metaobject protocol, +see @ref{Metaobjects and the Metaobject Protocol}. + +The aim of the MOP specification in this chapter is to specify all the +customizable generic function invocations that can be made by the standard +GOOPS syntax, procedures and methods, and to explain the protocol for +customizing such invocations. + +A generic function invocation is customizable if the types of the arguments +to which it is applied are not all determined by the lexical context in +which the invocation appears. For example, + +@itemize @bullet +@item +the @code{(initialize @var{instance} @var{initargs})} invocation in the +default @code{make-instance} method is customizable, because the type of the +@code{@var{instance}} argument is determined by the class that was passed to +@code{make-instance}. + +@item +the @code{(make <generic> #:name ',name)} invocation in @code{define-generic} +is not customizable, because all of its arguments have lexically determined +types. +@end itemize + +When using this rule to decide whether a given generic function invocation +is customizable, we ignore arguments that are expected to be handled in +method definitions as a single ``rest'' list argument. + +For each customizable generic function invocation, the @dfn{invocation +protocol} is explained by specifying + +@itemize @bullet +@item +what, conceptually, the applied method is intended to do + +@item +what assumptions, if any, the caller makes about the applied method's side +effects + +@item +what the caller expects to get as the applied method's return value. +@end itemize + +@menu +* Class Definition:: +* Instance Creation:: +* Class Redefinition:: +* Method Definition:: +* Generic Function Invocation:: +@end menu + +@node Class Definition +@section Class Definition + +@code{define-class} (syntax) + +@itemize @bullet +@item +@code{class} (syntax) + +@itemize @bullet +@item +@code{make-class} (procedure) + +@itemize @bullet +@item +@code{make @var{metaclass} @dots{}} (generic) + +@var{metaclass} is the metaclass of the class being defined, either +taken from the @code{#:metaclass} class option or computed by +@code{ensure-metaclass}. The applied method must create and return the +fully initialized class metaobject for the new class definition. +@end itemize + +@end itemize + +@item +@code{class-redefinition @var{old-class} @var{new-class}} (generic) + +@code{define-class} calls @code{class-redefinition} if the variable +specified by its first argument already held a GOOPS class definition. +@var{old-class} and @var{new-class} are the old and new class metaobjects. +The applied method should perform whatever is necessary to handle the +redefinition, and should return the class metaobject that is to be bound +to @code{define-class}'s variable. The default class redefinition +protocol is described in @ref{Class Redefinition}. +@end itemize + +The @code{(make @var{metaclass} @dots{})} invocation above will create +an class metaobject with metaclass @var{metaclass}. By default, this +metaobject will be initialized by the @code{initialize} method that is +specialized for instances of type @code{<class>}. + +@code{initialize <class> @var{initargs}} (method) + +@itemize @bullet +@item +@code{compute-cpl @var{class}} (generic) + +The applied method should compute and return the class precedence list +for @var{class} as a list of class metaobjects. When @code{compute-cpl} +is called, the following @var{class} metaobject slots have all been +initialized: @code{name}, @code{direct-supers}, @code{direct-slots}, +@code{direct-subclasses} (empty), @code{direct-methods}. The value +returned by @code{compute-cpl} will be stored in the @code{cpl} slot. + +@item +@code{compute-slots @var{class}} (generic) + +The applied method should compute and return the slots (union of direct +and inherited) for @var{class} as a list of slot definitions. When +@code{compute-slots} is called, all the @var{class} metaobject slots +mentioned for @code{compute-cpl} have been initialized, plus the +following: @code{cpl}, @code{redefined} (@code{#f}), @code{environment}. +The value returned by @code{compute-slots} will be stored in the +@code{slots} slot. + +@item +@code{compute-get-n-set @var{class} @var{slot-def}} (generic) + +@code{initialize} calls @code{compute-get-n-set} for each slot computed +by @code{compute-slots}. The applied method should compute and return a +pair of closures that, respectively, get and set the value of the specified +slot. The get closure should have arity 1 and expect a single argument +that is the instance whose slot value is to be retrieved. The set closure +should have arity 2 and expect two arguments, where the first argument is +the instance whose slot value is to be set and the second argument is the +new value for that slot. The closures should be returned in a two element +list: @code{(list @var{get} @var{set})}. + +The closures returned by @code{compute-get-n-set} are stored as part of +the value of the @var{class} metaobject's @code{getters-n-setters} slot. +Specifically, the value of this slot is a list with the same number of +elements as there are slots in the class, and each element looks either like + +@example +@code{(@var{slot-name-symbol} @var{init-function} . @var{index})} +@end example + +or like + +@example +@code{(@var{slot-name-symbol} @var{init-function} @var{get} @var{set})} +@end example + +Where the get and set closures are replaced by @var{index}, the slot is +an instance slot and @var{index} is the slot's index in the underlying +structure: GOOPS knows how to get and set the value of such slots and so +does not need specially constructed get and set closures. Otherwise, +@var{get} and @var{set} are the closures returned by @code{compute-get-n-set}. + +The structure of the @code{getters-n-setters} slot value is important when +understanding the next customizable generic functions that @code{initialize} +calls@dots{} + +@item +@code{compute-getter-method @var{class} @var{gns}} (generic) + +@code{initialize} calls @code{compute-getter-method} for each of the class's +slots (as determined by @code{compute-slots}) that includes a +@code{#:getter} or @code{#:accessor} slot option. @var{gns} is the +element of the @var{class} metaobject's @code{getters-n-setters} slot that +specifies how the slot in question is referenced and set, as described +above under @code{compute-get-n-set}. The applied method should create +and return a method that is specialized for instances of type @var{class} +and uses the get closure to retrieve the slot's value. [ *fixme Need +to insert something here about checking that the value is not unbound. ] +@code{initialize} uses @code{add-method!} to add the returned method to +the generic function named by the slot definition's @code{#:getter} or +@code{#:accessor} option. + +@item +@code{compute-setter-method @var{class} @var{gns}} (generic) + +@code{compute-setter-method} is invoked with the same arguments as +@code{compute-getter-method}, for each of the class's slots that includes +a @code{#:setter} or @code{#:accessor} slot option. The applied method +should create and return a method that is specialized for instances of +type @var{class} and uses the set closure to set the slot's value. +@code{initialize} then uses @code{add-method!} to add the returned method +to the generic function named by the slot definition's @code{#:setter} +or @code{#:accessor} option. +@end itemize + +@node Instance Creation +@section Instance Creation + +@code{make <class> . @var{initargs}} (method) + +@itemize @bullet +@item +@code{allocate-instance @var{class} @var{initargs}} (generic) + +The applied @code{allocate-instance} method should allocate storage for +a new instance of class @var{class} and return the uninitialized instance. + +@item +@code{initialize @var{instance} @var{initargs}} (generic) + +@var{instance} is the uninitialized instance returned by +@code{allocate-instance}. The applied method should initialize the new +instance in whatever sense is appropriate for its class. The method's +return value is ignored. +@end itemize + +@node Class Redefinition +@section Class Redefinition + +The default @code{class-redefinition} method, specialized for classes +with the default metaclass @code{<class>}, has the following internal +protocol. + +[ *fixme* I'm not sure that I understand this sufficiently to explain +it. Also, the internals of the default class redefinition method are +extremely implementation-specific, and I'm not sure that there is that +much point trying to describe the internal protocol such that it could +be customized without going to look at the source code. ] + +@code{class-redefinition @var{(old <class>)} @var{(new <class>)}} +(method) + +@itemize @bullet +@item +@code{remove-class-accessors! @var{old}} (generic) + +@item +@code{update-direct-method! @var{method} @var{old} @var{new}} (generic) + +@item +@code{update-direct-subclass! @var{subclass} @var{old} @var{new}} (generic) +@end itemize + +The default @code{update-direct-subclass!} method invokes +@code{class-redefinition} recursively to handle the redefinition of the +subclass. + +When a class is redefined, any existing instance of the redefined class +will be modified for the new class definition before the next time that +any of the instance's slot is referenced or set. GOOPS modifies each +instance by calling the generic function @code{change-class}. [ *fixme* +Actually it sometimes calls @code{change-class} and sometimes +@code{change-object-class}, and I don't understand why. ] + +The default @code{change-class} method copies slot values from the old +to the modified instance, and initializes new slots, as described in +@ref{Changing the Class of an Instance}. After doing so, it makes a +generic function invocation that can be used to customize the instance +update algorithm. + +@code{change-class @var{(old-instance <object>)} @var{(new <class>)}} (method) + +@itemize @bullet +@item +@code{update-instance-for-different-class @var{old-instance} @var{new-instance}} (generic) + +@code{change-class} invokes @code{update-instance-for-different-class} +as the last thing that it does before returning. The applied method can +make any further adjustments to @var{new-instance} that are required to +complete or modify the change of class. The return value from the +applied method is ignored. + +The default @code{update-instance-for-different-class} method does +nothing. +@end itemize + +@node Method Definition +@section Method Definition + +@code{define-method} (syntax) + +@itemize @bullet +@item +@code{add-method! @var{target} @var{method}} (generic) + +@code{define-method} invokes the @code{add-method!} generic function to +handle adding the new method to a variety of possible targets. GOOPS +includes methods to handle @var{target} as + +@itemize @bullet +@item +a generic function (the most common case) + +@item +a procedure + +@item +a primitive generic (@pxref{Extending Guiles Primitives}) +@end itemize + +By defining further methods for @code{add-method!}, you can +theoretically handle adding methods to further types of target. +@end itemize + +@node Generic Function Invocation +@section Generic Function Invocation + +[ *fixme* Description required here. ] + +@code{apply-generic} + +@itemize @bullet +@item +@code{no-method} + +@item +@code{compute-applicable-methods} + +@item +@code{sort-applicable-methods} + +@item +@code{apply-methods} + +@item +@code{no-applicable-method} +@end itemize + +@code{sort-applicable-methods} + +@itemize @bullet +@item +@code{method-more-specific?} +@end itemize + +@code{apply-methods} + +@itemize @bullet +@item +@code{apply-method} +@end itemize + +@code{next-method} + +@itemize @bullet +@item +@code{no-next-method} +@end itemize + +@node Tutorial, Index, MOP Specification, Top +@chapter Tutorial +@include goops-tutorial.texi + +@node Index, Concept Index, Tutorial, Top +@chapter Index +@page +@node Concept Index, Function and Variable Index, Index, Top +@unnumberedsec Concept Index + +@printindex cp + +@node Function and Variable Index, , Concept Index, Top +@unnumberedsec Function and Variable Index + +@printindex fn + +@summarycontents +@contents +@bye diff --git a/doc/goops/hierarchy.eps b/doc/goops/hierarchy.eps new file mode 100644 index 000000000..7b1a98605 --- /dev/null +++ b/doc/goops/hierarchy.eps @@ -0,0 +1,127 @@ +%!PS-Adobe-2.0 EPSF +%%Title: /tmp/xfig-fig016295 +%%Creator: fig2dev +%%CreationDate: Fri Jun 10 23:18:16 1994 +%%For: eg@kaolin (Erick Gallesio) +%%BoundingBox: 0 0 361 217 +%%Pages: 0 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/l {lineto} bind def +/m {moveto} bind def +/s {stroke} bind def +/n {newpath} bind def +/gs {gsave} bind def +/gr {grestore} bind def +/clp {closepath} bind def +/graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul +4 -2 roll mul setrgbcolor} bind def +/col-1 {} def +/col0 {0 0 0 setrgbcolor} bind def +/col1 {0 0 1 setrgbcolor} bind def +/col2 {0 1 0 setrgbcolor} bind def +/col3 {0 1 1 setrgbcolor} bind def +/col4 {1 0 0 setrgbcolor} bind def +/col5 {1 0 1 setrgbcolor} bind def +/col6 {1 1 0 setrgbcolor} bind def +/col7 {1 1 1 setrgbcolor} bind def + end +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def +%%EndProlog + +$F2psBegin +0 setlinecap 0 setlinejoin +-216.0 288.0 translate 0.900 -0.900 scale +0.500 setlinewidth +n 309 159 m 309 159 l gs col-1 s gr +n 246.401 216.889 m 244.000 209.000 l 249.831 214.831 l gs 2 setlinejoin col-1 s gr +% Polyline +n 244 209 m 274 259 l gs col-1 s gr +n 298.169 214.831 m 304.000 209.000 l 301.599 216.889 l gs 2 setlinejoin col-1 s gr +% Polyline +n 304 209 m 274 259 l gs col-1 s gr +n 255.721 213.778 m 249.000 209.000 l 257.179 210.053 l gs 2 setlinejoin col-1 s gr +% Polyline +n 249 209 m 364 254 l gs col-1 s gr +n 370.312 216.376 m 374.000 209.000 l 374.217 217.243 l gs 2 setlinejoin col-1 s gr +% Polyline +n 374 209 m 364 254 l gs col-1 s gr +n 283.772 280.725 m 279.000 274.000 l 286.376 277.688 l gs 2 setlinejoin col-1 s gr +% Polyline +n 279 274 m 314 304 l gs col-1 s gr +n 351.457 272.333 m 359.000 269.000 l 353.913 275.490 l gs 2 setlinejoin col-1 s gr +% Polyline +n 359 269 m 314 304 l gs col-1 s gr +n 300.950 165.789 m 309.000 164.000 l 302.739 169.367 l gs 2 setlinejoin col-1 s gr +% Polyline +n 309 164 m 249 194 l gs col-1 s gr +n 307.000 172.000 m 309.000 164.000 l 311.000 172.000 l gs 2 setlinejoin col-1 s gr +% Polyline +n 309 164 m 309 199 l gs col-1 s gr +n 315.261 169.367 m 309.000 164.000 l 317.050 165.789 l gs 2 setlinejoin col-1 s gr +% Polyline +n 309 164 m 379 199 l gs col-1 s gr +n 406.949 101.701 m 404.000 94.000 l 410.226 99.407 l gs 2 setlinejoin col-1 s gr +% Polyline +n 404 94 m 439 144 l gs col-1 s gr +n 410.363 99.245 m 404.000 94.000 l 412.083 95.634 l gs 2 setlinejoin col-1 s gr +% Polyline +n 404 94 m 509 144 l gs col-1 s gr +n 411.173 98.068 m 404.000 94.000 l 412.243 94.214 l gs 2 setlinejoin col-1 s gr +% Polyline +n 404 94 m 584 144 l gs col-1 s gr +n 396.075 96.277 m 404.000 94.000 l 398.079 99.739 l gs 2 setlinejoin col-1 s gr +% Polyline +n 404 94 m 309 149 l gs col-1 s gr +% Polyline +n 584 229 m 584 204 l gs col-1 s gr +n 582.000 212.000 m 584.000 204.000 l 586.000 212.000 l gs 2 setlinejoin col-1 s gr +% Polyline +n 584 189 m 584 159 l gs col-1 s gr +n 582.000 167.000 m 584.000 159.000 l 586.000 167.000 l gs 2 setlinejoin col-1 s gr +/Times-Bold findfont 12.00 scalefont setfont +239 209 m +gs 1 -1 scale (A) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +274 274 m +gs 1 -1 scale (D) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +359 269 m +gs 1 -1 scale (E) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +304 209 m +gs 1 -1 scale (B) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +374 209 m +gs 1 -1 scale (C) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +314 319 m +gs 1 -1 scale (F) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +289 159 m +gs 1 -1 scale (<object>) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +389 89 m +gs 1 -1 scale (<top>) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +424 154 m +gs 1 -1 scale (<pair>) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +474 154 m +gs 1 -1 scale (<procedure>) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +559 154 m +gs 1 -1 scale (<number>) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +629 154 m +gs 1 -1 scale (...) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +569 199 m +gs 1 -1 scale (<real>) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +559 239 m +gs 1 -1 scale (<integer>) col-1 show gr +$F2psEnd diff --git a/doc/goops/hierarchy.txt b/doc/goops/hierarchy.txt new file mode 100644 index 000000000..c7992df7b --- /dev/null +++ b/doc/goops/hierarchy.txt @@ -0,0 +1,14 @@ + <top> + / \\\_____________________ + / \\___________ \ + / \ \ \ + <object> <pair> <procedure> <number> + / | \ | + / | \ | + A B C <complex> + |\__/__ | | + \ / \ / | + D E <real> + \ / | + F | + <integer> diff --git a/doc/goops/mop.text b/doc/goops/mop.text new file mode 100644 index 000000000..0180f2c1e --- /dev/null +++ b/doc/goops/mop.text @@ -0,0 +1,66 @@ +*** NOTE: This information needs updating! *** + +P - procedure +L - local procedure +S - syntax +G - generic +M - method + +define-class (S) + make-class (S) + ensure-metaclass (P) + ensure-metaclass-with-supers (P) + make (G) + ensure-class (P) + make (G) + class-redefinition (G) + remove-class-accessors (G) + update-direct-method (G) + update-direct-subclass (G) + +define-generic (S) + make-generic-function (S) + ensure-generic-function (P) + make (G) + +define-method (S) + ensure-method (P) + ensure-generic-function (P) + make (G) + make (G) + add-method (P) + +method (S) + ensure-method (P) + +initialize (class) (M) + compute-cpl (P) + compute-slots (G) + compute-getters-n-setters (P) + compute-slot-init-function (L) + compute-get-n-set (G) + compute-slot-accessors (P) + ensure-method (P) + %inherit-magic! (P) + %prep-layout! (P) + +initialize (generic) (M) + make (G) + +change-class (G) + change-object-class (P) + update-instance-for-different-class (G) + +make = make-instance (G) + allocate-instance (G) + %allocate-instance (P) + initialize (G) + %initialize-object (P) + +apply-generic (G) + compute-applicable-methods (G) + find-method (P) + sort-applicable-methods (G) + sort (P) + apply-methods (G) + apply-method (G) diff --git a/doc/guile-tut.texi b/doc/guile-tut.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/guile-tut.texi +++ /dev/null diff --git a/doc/hierarchy.eps b/doc/hierarchy.eps deleted file mode 100644 index e69de29bb..000000000 --- a/doc/hierarchy.eps +++ /dev/null diff --git a/doc/hierarchy.txt b/doc/hierarchy.txt deleted file mode 100644 index e69de29bb..000000000 --- a/doc/hierarchy.txt +++ /dev/null diff --git a/doc/indices.texi b/doc/indices.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/indices.texi +++ /dev/null diff --git a/doc/misc-modules.texi b/doc/misc-modules.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/misc-modules.texi +++ /dev/null diff --git a/doc/mop.text b/doc/mop.text deleted file mode 100644 index e69de29bb..000000000 --- a/doc/mop.text +++ /dev/null diff --git a/doc/new-docstrings.texi b/doc/new-docstrings.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/new-docstrings.texi +++ /dev/null diff --git a/doc/posix.texi b/doc/posix.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/posix.texi +++ /dev/null diff --git a/doc/preface.texi b/doc/preface.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/preface.texi +++ /dev/null diff --git a/doc/r5rs.texi b/doc/r5rs.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/r5rs.texi +++ /dev/null diff --git a/doc/r5rs/.cvsignore b/doc/r5rs/.cvsignore new file mode 100644 index 000000000..8eaa8267a --- /dev/null +++ b/doc/r5rs/.cvsignore @@ -0,0 +1,23 @@ +Makefile +Makefile.in +stamp-vti +stamp-vti.1 +*.log +*.dvi +*.aux +*.toc +*.cp +*.fn +*.vr +*.tp +*.ky +*.pg +*.cps +*.fns +*.tps +*.vrs +*.ps +*.info* +*.html +version.texi +version-tutorial.texi diff --git a/doc/r5rs/r5rs.texi b/doc/r5rs/r5rs.texi new file mode 100644 index 000000000..a33771190 --- /dev/null +++ b/doc/r5rs/r5rs.texi @@ -0,0 +1,8538 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename r5rs.info +@settitle Revised(5) Scheme + +@c This copy of r5rs.texi differs from Aubrey Jaffer's master copy +@c by a set of changes to allow the building of r5rs.dvi from r5rs.texi. +@c Aubrey Jaffer's view - which I agree with - is that, given that +@c people have the option of building r5rs.dvi from the original +@c LaTeX distribution for R5RS, it is not worth fixing his master +@c copy of r5rs.texi and the tool which autogenerates it. On the +@c other hand, it is a marginal convenience for people to be able to +@c build hardcopy from r5rs.texi, even if the results are less good +@c than with the original LaTeX. Hence the following fixes. +@c (lines 714, 725, 728, 1614, 2258): Remove invalid parentheses from +@c @deffn statements. +@c (line 2316): Change @deffnx to @deffn, and insert `@end deffn' to +@c terminate preceding @deffn. +@c (line 7320): Insert `@c ' at beginning of lines that are intended +@c to be @ignore'd. +@c +@c NJ 2001/1/26 + +@c \documentclass[twoside]{algol60} + +@c \pagestyle{headings} +@c \showboxdepth=0 + + + +@c \def\headertitle{Revised$^{5}$ Scheme} +@c \def\integerversion{5} + +@c Sizes and dimensions + +@c \topmargin -.375in % Nominal distance from top of page to top of + +@c box containing running head. +@c \headsep 15pt % Space between running head and text. + +@c \textheight 663pt % Height of text (including footnotes and figures, + +@c excluding running head and foot). + +@c \textwidth 523pt % Width of text line. +@c \columnsep 15pt % Space between columns +@c \columnseprule 0pt % Width of rule between columns. + +@c \parskip 5pt plus 2pt minus 2pt % Extra vertical space between paragraphs. +@c \parindent 0pt % Width of paragraph indentation. +@c \topsep 0pt plus 2pt % Extra vertical space, in addition to + +@c \parskip, added above and below list and + +@c paragraphing environments. + +@c \oddsidemargin -.5in % Left margin on odd-numbered pages. +@c \evensidemargin -.5in % Left margin on even-numbered pages. + +@c % End of sizes and dimensions + +@paragraphindent 0 +@c %**end of header +@c syncodeindex fn cp + +@ifinfo +@dircategory The Algorithmic Language Scheme +@direntry +* R5RS: (r5rs). The Revised(5) Report on Scheme. +@end direntry +@end ifinfo + + +@c \parindent 0pt %!! 15pt % Width of paragraph indentation. + + @b{20 February 1998} +@c \hfil \today{} + +@c @include{first} +@titlepage + +@c HTML first page +@title Scheme +@subtitle Revised(5) Report on the Algorithmic Language Scheme +@c First page + +@c \thispagestyle{empty} + +@c \todo{"another" report?} + + +@author R@sc{ICHARD} K@sc{ELSEY}, W@sc{ILLIAM} C@sc{LINGER, AND} J@sc{ONATHAN} R@sc{EES} (@i{Editors}) +@author H. A@sc{BELSON} +@author R. K. D@sc{YBVIG} +@author C. T. H@sc{AYNES} +@author G. J. R@sc{OZAS} +@author N. I. A@sc{DAMS IV} +@author D. P. F@sc{RIEDMAN} +@author E. K@sc{OHLBECKER} +@author G. L. S@sc{TEELE} J@sc{R}. +@author D. H. B@sc{ARTLEY} +@author R. H@sc{ALSTEAD} +@author D. O@sc{XLEY} +@author G. J. S@sc{USSMAN} +@author G. B@sc{ROOKS} +@author C. H@sc{ANSON} +@author K. M. P@sc{ITMAN} +@author M. W@sc{AND} +@author + + +@c {\it Dedicated to the Memory of ALGOL 60} +@i{Dedicated to the Memory of Robert Hieb} +@c [For the macros in R5RS -RK] + + + + +@unnumbered Summary + + +The report gives a defining description of the programming language +Scheme. Scheme is a statically scoped and properly tail-recursive +dialect of the Lisp programming language invented by Guy Lewis +Steele Jr.@: and Gerald Jay Sussman. It was designed to have an +exceptionally clear and simple semantics and few different ways to +form expressions. A wide variety of programming paradigms, including +imperative, functional, and message passing styles, find convenient +expression in Scheme. + +The introduction offers a brief history of the language and of +the report. + +The first three chapters present the fundamental ideas of the +language and describe the notational conventions used for describing the +language and for writing programs in the language. + +Chapters @ref{Expressions} and @ref{Program structure} describe +the syntax and semantics of expressions, programs, and definitions. + +Chapter @ref{Standard procedures} describes Scheme's built-in +procedures, which include all of the language's data manipulation and +input/output primitives. + +Chapter @ref{Formal syntax and semantics} provides a formal syntax for Scheme +written in extended BNF, along with a formal denotational semantics. +An example of the use of the language follows the formal syntax and +semantics. + +The report concludes with a list of references and an +alphabetic index. + +@ignore todo +expand the summary so that it fills up the column. +@end ignore + + +@c \vfill +@c \begin{center} +@c {\large \bf +@c *** DRAFT*** \\ +@c %August 31, 1989 +@c \today +@c }\end{center} + + + + + +@c \addvspace{3.5pt} % don't shrink this gap +@c \renewcommand{\tocshrink}{-3.5pt} % value determined experimentally + + + + + + +@page + +@end titlepage + +@c INFO first page +@ifinfo + +@c First page + +@c \thispagestyle{empty} + +@c \todo{"another" report?} + + +@node top, Introduction, (dir), (dir) +@top Revised(5) Report on the Algorithmic Language Scheme + +@sp 1 + + +@center @c begin-tabular +@quotation +@multitable @columnfractions 0.25 0.25 0.25 0.25 +@item +@center R@sc{ICHARD} K@sc{ELSEY}, W@sc{ILLIAM} C@sc{LINGER, AND} J@sc{ONATHAN} R@sc{EES} (@i{Editors}) +@item H. A@sc{BELSON} @tab R. K. D@sc{YBVIG} @tab C. T. H@sc{AYNES} @tab G. J. R@sc{OZAS} +@item N. I. A@sc{DAMS IV} @tab D. P. F@sc{RIEDMAN} @tab E. K@sc{OHLBECKER} @tab G. L. S@sc{TEELE} J@sc{R}. +@item D. H. B@sc{ARTLEY} @tab R. H@sc{ALSTEAD} @tab D. O@sc{XLEY} @tab G. J. S@sc{USSMAN} +@item G. B@sc{ROOKS} @tab C. H@sc{ANSON} @tab K. M. P@sc{ITMAN} @tab M. W@sc{AND} +@item +@end multitable +@end quotation + + +@sp 2 + +@c {\it Dedicated to the Memory of ALGOL 60} +@i{Dedicated to the Memory of Robert Hieb} +@c [For the macros in R5RS -RK] + +@sp 3 + + + + +@majorheading Summary + + +The report gives a defining description of the programming language +Scheme. Scheme is a statically scoped and properly tail-recursive +dialect of the Lisp programming language invented by Guy Lewis +Steele Jr.@: and Gerald Jay Sussman. It was designed to have an +exceptionally clear and simple semantics and few different ways to +form expressions. A wide variety of programming paradigms, including +imperative, functional, and message passing styles, find convenient +expression in Scheme. + +The introduction offers a brief history of the language and of +the report. + +The first three chapters present the fundamental ideas of the +language and describe the notational conventions used for describing the +language and for writing programs in the language. + +Chapters @ref{Expressions} and @ref{Program structure} describe +the syntax and semantics of expressions, programs, and definitions. + +Chapter @ref{Standard procedures} describes Scheme's built-in +procedures, which include all of the language's data manipulation and +input/output primitives. + +Chapter @ref{Formal syntax and semantics} provides a formal syntax for Scheme +written in extended BNF, along with a formal denotational semantics. +An example of the use of the language follows the formal syntax and +semantics. + +The report concludes with a list of references and an +alphabetic index. + +@ignore todo +expand the summary so that it fills up the column. +@end ignore + + +@c \vfill +@c \begin{center} +@c {\large \bf +@c *** DRAFT*** \\ +@c %August 31, 1989 +@c \today +@c }\end{center} + + + + + +@c \addvspace{3.5pt} % don't shrink this gap +@c \renewcommand{\tocshrink}{-3.5pt} % value determined experimentally + +@unnumbered Contents + +@menu +* Introduction:: +* Overview of Scheme:: +* Lexical conventions:: +* Basic concepts:: +* Expressions:: +* Program structure:: +* Standard procedures:: +* Formal syntax and semantics:: +* Notes:: +* Additional material:: +* Example:: +* Bibliography:: +* Index:: +@end menu + + + + + +@page + +@end ifinfo + + +@c @include{intro} +@node Introduction, Overview of Scheme, top, top +@unnumbered Introduction + +@menu +* Background:: +* Acknowledgements:: +@end menu + + + + +Programming languages should be designed not by piling feature on top of +feature, but by removing the weaknesses and restrictions that make additional +features appear necessary. Scheme demonstrates that a very small number +of rules for forming expressions, with no restrictions on how they are +composed, suffice to form a practical and efficient programming language +that is flexible enough to support most of the major programming +paradigms in use today. + +@c Scheme has influenced the evolution of Lisp. +Scheme +was one of the first programming languages to incorporate first class +procedures as in the lambda calculus, thereby proving the usefulness of +static scope rules and block structure in a dynamically typed language. +Scheme was the first major dialect of Lisp to distinguish procedures +from lambda expressions and symbols, to use a single lexical +environment for all variables, and to evaluate the operator position +of a procedure call in the same way as an operand position. By relying +entirely on procedure calls to express iteration, Scheme emphasized the +fact that tail-recursive procedure calls are essentially goto's that +pass arguments. Scheme was the first widely used programming language to +embrace first class escape procedures, from which all previously known +sequential control structures can be synthesized. A subsequent +version of Scheme introduced the concept of exact and inexact numbers, +an extension of Common Lisp's generic arithmetic. +More recently, Scheme became the first programming language to support +hygienic macros, which permit the syntax of a block-structured language +to be extended in a consistent and reliable manner. +@c A few +@c of these innovations have recently been incorporated into Common Lisp, while +@c others remain to be adopted. + +@ignore todo +Ramsdell: +I would like to make a few comments on presentation. The most +important comment is about section organization. Newspaper writers +spend most of their time writing the first three paragraphs of any +article. This part of the article is often the only part read by +readers, and is important in enticing readers to continue. In the +same way, The first page is most likely to be the only page read by +many SIGPLAN readers. If I had my choice of what I would ask them to +read, it would be the material in section 1.1, the Semantics section +that notes that scheme is lexically scoped, tail recursive, weakly +typed, ... etc. I would expand on the discussion on continuations, +as they represent one important difference between Scheme and other +languages. The introduction, with its history of scheme, its history +of scheme reports and meetings, and acknowledgements giving names of +people that the reader will not likely know, is not that one page I +would like all to read. I suggest moving the history to the back of +the report, and use the first couple of pages to convince the reader +that the language documented in this report is worth studying. + +@end ignore + + +@node Background, Acknowledgements, Introduction, Introduction +@unnumberedsec Background + + +The first description of Scheme was written in +1975 [Scheme75]. A revised report [Scheme78] +@ignore todo +italicize or not? +@end ignore + appeared in 1978, which described the evolution +of the language as its MIT implementation was upgraded to support an +innovative compiler [Rabbit]. Three distinct projects began in +1981 and 1982 to use variants of Scheme for courses at MIT, Yale, and +Indiana University [Rees82], [MITScheme], [Scheme311]. An introductory +computer science textbook using Scheme was published in +1984 [SICP]. + +@c \vest As might be expected of a language used primarily for education and +@c research, Scheme has always evolved rapidly. This was no problem when +@c Scheme was used only within MIT, but +As Scheme became more widespread, +local dialects began to diverge until students and researchers +occasionally found it difficult to understand code written at other +sites. +Fifteen representatives of the major implementations of Scheme therefore +met in October 1984 to work toward a better and more widely accepted +standard for Scheme. +@c Participating in this workshop were Hal Abelson, Norman Adams, David +@c Bartley, Gary Brooks, William Clinger, Daniel Friedman, Robert Halstead, +@c Chris Hanson, Christopher Haynes, Eugene Kohlbecker, Don Oxley, Jonathan Rees, +@c Guillermo Rozas, Gerald Jay Sussman, and Mitchell Wand. Kent Pitman +@c made valuable contributions to the agenda for the workshop but was +@c unable to attend the sessions. + +@c Subsequent electronic mail discussions and committee work completed the +@c definition of the language. +@c Gerry Sussman drafted the section on numbers, Chris Hanson drafted the +@c sections on characters and strings, and Gary Brooks and William Clinger +@c drafted the sections on input and output. +@c William Clinger recorded the decisions of the workshop and +@c compiled the pieces into a coherent document. +@c The ``Revised revised report on Scheme''~\cite{RRRS} +Their report [RRRS] +was published at MIT and Indiana University in the summer of 1985. +Further revision took place in the spring of 1986 [R3RS], +@c , again accomplished +@c almost entirely by electronic mail, resulted in the present report. +and in the spring of 1988 [R4RS]. +The present report reflects further revisions agreed upon in a meeting +at Xerox PARC in June 1992. + +@c \vest The number 3 in the title is part of the title, not a reference to +@c a footnote. The word ``revised'' is raised to the third power because +@c the report is a revision of a report that was already twice revised. + +@ignore todo +Write an editors' note? +@end ignore + + + +@sp 3 + +We intend this report to belong to the entire Scheme community, and so +we grant permission to copy it in whole or in part without fee. In +particular, we encourage implementors of Scheme to use this report as +a starting point for manuals and other documentation, modifying it as +necessary. + + + + +@node Acknowledgements, , Background, Introduction +@unnumberedsec Acknowledgements + + +We would like to thank the following people for their help: Alan Bawden, Michael +Blair, George Carrette, Andy Cromarty, Pavel Curtis, Jeff Dalton, Olivier Danvy, +Ken Dickey, Bruce Duba, Marc Feeley, +Andy Freeman, Richard Gabriel, Yekta G"ursel, Ken Haase, Robert +Hieb, Paul Hudak, Morry Katz, Chris Lindblad, Mark Meyer, Jim Miller, Jim Philbin, +John Ramsdell, Mike Shaff, Jonathan Shapiro, Julie Sussman, +Perry Wagle, Daniel Weise, Henry Wu, and Ozan Yigit. +We thank Carol Fessenden, Daniel +Friedman, and Christopher Haynes for permission to use text from the Scheme 311 +version 4 reference manual. We thank Texas Instruments, Inc. for permission to +use text from the @emph{TI Scheme Language Reference Manual}[TImanual85]. +We gladly acknowledge the influence of manuals for MIT Scheme[MITScheme], +T[Rees84], Scheme 84[Scheme84],Common Lisp[CLtL], +and Algol 60[Naur63]. + +We also thank Betty Dexter for the extreme effort she put into +setting this report in @TeX{}, and Donald Knuth for designing the program +that caused her troubles. + +The Artificial Intelligence Laboratory of the +Massachusetts Institute of Technology, the Computer Science +Department of Indiana University, the Computer and Information +Sciences Department of the University of Oregon, and the NEC Research +Institute supported the preparation of this report. Support for the MIT +work was provided in part by +the Advanced Research Projects Agency of the Department of Defense under Office +of Naval Research contract N00014-80-C-0505. Support for the Indiana +University work was provided by NSF grants NCS 83-04567 and NCS +83-03325. + + + + +@sp 2 + +@c \clearchapterstar{Description of the language} %\unskip\vskip -2ex +@c @include{struct} + +@c 1. Structure of the language + +@node Overview of Scheme, Lexical conventions, Introduction, top +@chapter Overview of Scheme + +@menu +* Semantics:: +* Syntax:: +* Notation and terminology:: +@end menu + + +@node Semantics, Syntax, Overview of Scheme, Overview of Scheme +@section Semantics + + + +This section gives an overview of Scheme's semantics. A +detailed informal semantics is the subject of +chapters @ref{Basic concepts} through @ref{Standard procedures}. For reference +purposes, section @ref{Formal semantics} provides a formal +semantics of Scheme. + +Following Algol, Scheme is a statically scoped programming +language. Each use of a variable is associated with a lexically +apparent binding of that variable. + +Scheme has latent as opposed to manifest types. Types +are associated with values (also called objects) rather than +@cindex @w{object} +with variables. (Some authors refer to languages with latent types as +weakly typed or dynamically typed languages.) Other languages with +latent types are APL, Snobol, and other dialects of Lisp. Languages +with manifest types (sometimes referred to as strongly typed or +statically typed languages) include Algol 60, Pascal, and C. + +All objects created in the course of a Scheme computation, including +procedures and continuations, have unlimited extent. +No Scheme object is ever destroyed. The reason that +implementations of Scheme do not (usually!) run out of storage is that +they are permitted to reclaim the storage occupied by an object if +they can prove that the object cannot possibly matter to any future +computation. Other languages in which most objects have unlimited +extent include APL and other Lisp dialects. + +Implementations of Scheme are required to be properly tail-recursive. +This allows the execution of an iterative computation in constant space, +even if the iterative computation is described by a syntactically +recursive procedure. Thus with a properly tail-recursive implementation, +iteration can be expressed using the ordinary procedure-call +mechanics, so that special iteration constructs are useful only as +syntactic sugar. See section @ref{Proper tail recursion}. + +Scheme procedures are objects in their own right. Procedures can be +created dynamically, stored in data structures, returned as results of +procedures, and so on. Other languages with these properties include +Common Lisp and ML. +@ignore todo +Rozas: Scheme had them first. +@end ignore + + +One distinguishing feature of Scheme is that continuations, which +in most other languages only operate behind the scenes, also have +``first-class'' status. Continuations are useful for implementing a +wide variety of advanced control constructs, including non-local exits, +backtracking, and coroutines. See section @ref{Control features}. + +Arguments to Scheme procedures are always passed by value, which +means that the actual argument expressions are evaluated before the +procedure gains control, whether the procedure needs the result of the +evaluation or not. ML, C, and APL are three other languages that always +pass arguments by value. +This is distinct from the lazy-evaluation semantics of Haskell, +or the call-by-name semantics of Algol 60, where an argument +expression is not evaluated unless its value is needed by the +procedure. + +@ignore todo +Lisp's call by value should be explained more +accurately. What's funny is that all values are references. +@end ignore + + +Scheme's model of arithmetic is designed to remain as independent as +possible of the particular ways in which numbers are represented within a +computer. In Scheme, every integer is a rational number, every rational is a +real, and every real is a complex number. Thus the distinction between integer +and real arithmetic, so important to many programming languages, does not +appear in Scheme. In its place is a distinction between exact arithmetic, +which corresponds to the mathematical ideal, and inexact arithmetic on +approximations. As in Common Lisp, exact arithmetic is not limited to +integers. + +@node Syntax, Notation and terminology, Semantics, Overview of Scheme +@section Syntax + + +Scheme, like most dialects of Lisp, employs a fully parenthesized prefix +notation for programs and (other) data; the grammar of Scheme generates a +sublanguage of the language used for data. An important +consequence of this simple, uniform representation is the susceptibility of +Scheme programs and data to uniform treatment by other Scheme programs. +For example, the @samp{eval} procedure evaluates a Scheme program expressed +as data. + +The @samp{read} procedure performs syntactic as well as lexical decomposition of +the data it reads. The @samp{read} procedure parses its input as data +(section @pxref{External representation}), not as program. + +The formal syntax of Scheme is described in section @ref{Formal syntax}. + + +@node Notation and terminology, , Syntax, Overview of Scheme +@section Notation and terminology + +@menu +* Primitive; library; and optional features:: +* Error situations and unspecified behavior:: +* Entry format:: +* Evaluation examples:: +* Naming conventions:: +@end menu + + + +@node Primitive; library; and optional features, Error situations and unspecified behavior, Notation and terminology, Notation and terminology +@subsection Primitive; library; and optional features + + + +It is required that every implementation of Scheme support all +features that are not marked as being @dfn{optional}. Implementations are +@cindex @w{optional} +free to omit optional features of Scheme or to add extensions, +provided the extensions are not in conflict with the language reported +here. In particular, implementations must support portable code by +providing a syntactic mode that preempts no lexical conventions of this +report. + +To aid in understanding and implementing Scheme, some features are marked +as @dfn{library}. These can be easily implemented in terms of the other, +@cindex @w{library} +primitive, features. They are redundant in the strict sense of +the word, but they capture common patterns of usage, and are therefore +provided as convenient abbreviations. + +@node Error situations and unspecified behavior, Entry format, Primitive; library; and optional features, Notation and terminology +@subsection Error situations and unspecified behavior + + + +@cindex @w{error} +When speaking of an error situation, this report uses the phrase ``an +error is signalled'' to indicate that implementations must detect and +report the error. If such wording does not appear in the discussion of +an error, then implementations are not required to detect or report the +error, though they are encouraged to do so. An error situation that +implementations are not required to detect is usually referred to simply +as ``an error.'' + +For example, it is an error for a procedure to be passed an argument that +the procedure is not explicitly specified to handle, even though such +domain errors are seldom mentioned in this report. Implementations may +extend a procedure's domain of definition to include such arguments. + +This report uses the phrase ``may report a violation of an +implementation restriction'' to indicate circumstances under which an +implementation is permitted to report that it is unable to continue +execution of a correct program because of some restriction imposed by the +implementation. Implementation restrictions are of course discouraged, +but implementations are encouraged to report violations of implementation +restrictions. +@cindex @w{implementation restriction} + +For example, an implementation may report a violation of an +implementation restriction if it does not have enough storage to run a +program. + +If the value of an expression is said to be ``unspecified,'' then +the expression must evaluate to some object without signalling an error, +but the value depends on the implementation; this report explicitly does +not say what value should be returned. +@cindex @w{unspecified} + +@ignore todo +Talk about unspecified behavior vs. unspecified values. +@end ignore + + +@ignore todo +Look at KMP's situations paper. +@end ignore + + + +@node Entry format, Evaluation examples, Error situations and unspecified behavior, Notation and terminology +@subsection Entry format + + +Chapters @ref{Expressions} and @ref{Standard procedures} are organized +into entries. Each entry describes one language feature or a group of +related features, where a feature is either a syntactic construct or a +built-in procedure. An entry begins with one or more header lines of the form + + +@noindent +@deffn {@var{category}} @var{template} + +@end deffn + +for required, primitive features, or + + +@noindent +@deffn {@var{qualifier} @var{category}} @var{template} + +@end deffn + +where @var{qualifier} is either ``library'' or ``optional'' as defined + in section @ref{Primitive; library; and optional features}. + +If @var{category} is ``syntax'', the entry describes an expression +type, and the template gives the syntax of the expression type. +Components of expressions are designated by syntactic variables, which +are written using angle brackets, for example, @r{<expression>}, +@r{<variable>}. Syntactic variables should be understood to denote segments of +program text; for example, @r{<expression>} stands for any string of +characters which is a syntactically valid expression. The notation + +@format + @r{<thing1>} @dots{} +@end format + +indicates zero or more occurrences of a @r{<thing>}, and + +@format + @r{<thing1>} @r{<thing2>} @dots{} +@end format + +indicates one or more occurrences of a @r{<thing>}. + +If @var{category} is ``procedure'', then the entry describes a procedure, and +the header line gives a template for a call to the procedure. Argument +names in the template are @var{italicized}. Thus the header line + + +@noindent +@deffn {procedure} vector-ref @var{vector} @var{k} + +@end deffn + +indicates that the built-in procedure @t{vector-ref} takes +two arguments, a vector @var{vector} and an exact non-negative integer +@var{k} (see below). The header lines + + +@noindent + +@deffn {procedure} make-vector @var{k} + + +@deffnx {procedure} make-vector @var{k} @var{fill} + +@end deffn + +indicate that the @t{make-vector} procedure must be defined to take +either one or two arguments. + + +It is an error for an operation to be presented with an argument that it +is not specified to handle. For succinctness, we follow the convention +that if an argument name is also the name of a type listed in +section @ref{Disjointness of types}, then that argument must be of the named type. +For example, the header line for @t{vector-ref} given above dictates that the +first argument to @t{vector-ref} must be a vector. The following naming +conventions also imply type restrictions: +@c \newcommand{\foo}[1]{\vr{#1}, \vri{#1}, $\ldots$ \vrj{#1}, $\ldots$} + + +@center @c begin-tabular +@quotation +@table @asis +@item @var{obj} +any object +@item @var{list}, @var{list1}, @dots{} @var{listj}, @dots{} +list (see section @pxref{Pairs and lists}) +@item @var{z}, @var{z1}, @dots{} @var{zj}, @dots{} +complex number +@item @var{x}, @var{x1}, @dots{} @var{xj}, @dots{} +real number +@item @var{y}, @var{y1}, @dots{} @var{yj}, @dots{} +real number +@item @var{q}, @var{q1}, @dots{} @var{qj}, @dots{} +rational number +@item @var{n}, @var{n1}, @dots{} @var{nj}, @dots{} +integer +@item @var{k}, @var{k1}, @dots{} @var{kj}, @dots{} +exact non-negative integer +@item +@end table +@end quotation + + + + +@ignore todo +Provide an example entry?? +@end ignore + + + +@node Evaluation examples, Naming conventions, Entry format, Notation and terminology +@subsection Evaluation examples + + +The symbol ``@result{}'' used in program examples should be read +``evaluates to.'' For example, + + +@example + +(* 5 8) ==> 40 + +@end example + + +means that the expression @t{(* 5 8)} evaluates to the object @t{40}. +Or, more precisely: the expression given by the sequence of characters +``@t{(* 5 8)}'' evaluates, in the initial environment, to an object +that may be represented externally by the sequence of characters ``@t{40}''. See section @ref{External representations} for a discussion of external +representations of objects. + +@node Naming conventions, , Evaluation examples, Notation and terminology +@subsection Naming conventions + + +By convention, the names of procedures that always return a boolean +value usually end +in ``@code{?}''. Such procedures are called predicates. +@vindex @w{?} + +By convention, the names of procedures that store values into previously +allocated locations (see section @pxref{Storage model}) usually end in +``@code{!}''. +@vindex @w{!} +Such procedures are called mutation procedures. +By convention, the value returned by a mutation procedure is unspecified. + +By convention, ``@code{->}'' appears within the names of procedures that +@vindex @w{->} +take an object of one type and return an analogous object of another type. +For example, @samp{list->vector} takes a list and returns a vector whose +elements are the same as those of the list. + + + +@ignore todo +Terms that need defining: thunk, command (what else?). +@end ignore + + +@c @include{lex} + +@c Lexical structure + +@c %\vfill\eject +@node Lexical conventions, Basic concepts, Overview of Scheme, top +@chapter Lexical conventions + +@menu +* Identifiers:: +* Whitespace and comments:: +* Other notations:: +@end menu + + +This section gives an informal account of some of the lexical +conventions used in writing Scheme programs. For a formal syntax of +Scheme, see section @ref{Formal syntax}. + +Upper and lower case forms of a letter are never distinguished +except within character and string constants. For example, @samp{Foo} is +the same identifier as @samp{FOO}, and @t{#x1AB} is the same number as +@t{#X1ab}. + +@node Identifiers, Whitespace and comments, Lexical conventions, Lexical conventions +@section Identifiers + + + +Most identifiers allowed by other programming +@cindex @w{identifier} +languages are also acceptable to Scheme. The precise rules for forming +identifiers vary among implementations of Scheme, but in all +implementations a sequence of letters, digits, and ``extended alphabetic +characters'' that begins with a character that cannot begin a number is +an identifier. In addition, @code{+}, @code{-}, and @code{...} are identifiers. +@vindex @w{...} +@vindex @w{-} +@vindex @w{+} +Here are some examples of identifiers: + + +@example + +lambda q +list->vector soup ++ V17a +<=? a34kTMNs +the-word-recursion-has-many-meanings + +@end example + + +Extended alphabetic characters may be used within identifiers as if +they were letters. The following are extended alphabetic characters: + + +@example + +! $ % & * + - . / : < = > ? @@ ^ _ ~ +@end example + + +See section @ref{Lexical structure} for a formal syntax of identifiers. + +Identifiers have two uses within Scheme programs: + + +@itemize @bullet + +@item +Any identifier may be used as a variable +or as a syntactic keyword +(see sections @pxref{Variables; syntactic keywords; and regions} and @pxref{Macros}). + +@item +When an identifier appears as a literal or within a literal +(see section @pxref{Literal expressions}), it is being used to denote a @emph{symbol} +(see section @pxref{Symbols}). + + +@end itemize + +@cindex @w{syntactic keyword} +@cindex @w{variable} + +@c \label{keywordsection} +@c The following identifiers are syntactic keywords, and should not be used +@c as variables: + +@c \begin{scheme} +@c => do or +@c and else quasiquote +@c begin if quote +@c case lambda set! +@c cond let unquote +@c define let* unquote-splicing +@c delay letrec% +@c \end{scheme} + +@c Some implementations allow all identifiers, including syntactic +@c keywords, to be used as variables. This is a compatible extension to +@c the language, but ambiguities in the language result when the +@c restriction is relaxed, and the ways in which these ambiguities are +@c resolved vary between implementations. + + +@node Whitespace and comments, Other notations, Identifiers, Lexical conventions +@section Whitespace and comments + + +@dfn{Whitespace} characters are spaces and newlines. +@cindex @w{Whitespace} +(Implementations typically provide additional whitespace characters such +as tab or page break.) Whitespace is used for improved readability and +as necessary to separate tokens from each other, a token being an +indivisible lexical unit such as an identifier or number, but is +otherwise insignificant. Whitespace may occur between any two tokens, +but not within a token. Whitespace may also occur inside a string, +where it is significant. + +A semicolon (@t{;}) indicates the start of a +comment. The comment continues to the +@cindex @w{;} +@cindex @w{comment} +end of the line on which the semicolon appears. Comments are invisible +to Scheme, but the end of the line is visible as whitespace. This +prevents a comment from appearing in the middle of an identifier or +number. + + +@example + +;;; The FACT procedure computes the factorial +;;; of a non-negative integer. +(define fact + (lambda (n) + (if (= n 0) + 1 ;Base case: return 1 + (* n (fact (- n 1)))))) + +@end example + + + +@node Other notations, , Whitespace and comments, Lexical conventions +@section Other notations + + +@ignore todo +Rewrite? +@end ignore + + +For a description of the notations used for numbers, see +section @ref{Numbers}. + + +@table @t + + +@item @t{.@: + -} +These are used in numbers, and may also occur anywhere in an identifier +except as the first character. A delimited plus or minus sign by itself +is also an identifier. +A delimited period (not occurring within a number or identifier) is used +in the notation for pairs (section @pxref{Pairs and lists}), and to indicate a +rest-parameter in a formal parameter list (section @pxref{Procedures}). +A delimited sequence of three successive periods is also an identifier. + +@item @t{( )} +Parentheses are used for grouping and to notate lists +(section @pxref{Pairs and lists}). + +@item @t{'} +The single quote character is used to indicate literal data (section @pxref{Literal expressions}). + +@item @t{`} +The backquote character is used to indicate almost-constant +data (section @pxref{Quasiquotation}). + +@item @t{, ,@@} +The character comma and the sequence comma at-sign are used in conjunction +with backquote (section @pxref{Quasiquotation}). + +@item @t{"} +The double quote character is used to delimit strings (section @pxref{Strings}). + +@item \ +Backslash is used in the syntax for character constants +(section @pxref{Characters}) and as an escape character within string +constants (section @pxref{Strings}). + +@c A box used because \verb is not allowed in command arguments. + +@item @w{@t{[ ] @{ @} |}} +Left and right square brackets and curly braces and vertical bar +are reserved for possible future extensions to the language. + +@item # + Sharp sign is used for a variety of purposes depending on +the character that immediately follows it: + +@item @t{#t} @t{#f} +These are the boolean constants (section @pxref{Booleans}). + +@item #\ +This introduces a character constant (section @pxref{Characters}). + +@item #@t{(} +This introduces a vector constant (section @pxref{Vectors}). Vector constants +are terminated by @t{)} . + +@item @t{#e #i #b #o #d #x} +These are used in the notation for numbers (section @pxref{Syntax of numerical constants}). + +@end table + + +@c @include{basic} + +@c \vfill\eject +@node Basic concepts, Expressions, Lexical conventions, top +@chapter Basic concepts + +@menu +* Variables; syntactic keywords; and regions:: +* Disjointness of types:: +* External representations:: +* Storage model:: +* Proper tail recursion:: +@end menu + + + +@node Variables; syntactic keywords; and regions, Disjointness of types, Basic concepts, Basic concepts +@section Variables; syntactic keywords; and regions + + + + +An identifier may name a type of syntax, or it may name +@cindex @w{identifier} +a location where a value can be stored. An identifier that names a type +of syntax is called a @emph{syntactic keyword} +@cindex @w{syntactic keyword} +and is said to be @emph{bound} to that syntax. An identifier that names a +location is called a @emph{variable} and is said to be +@cindex @w{variable} +@emph{bound} to that location. The set of all visible +bindings in effect at some point in a program is +@cindex @w{binding} +known as the @emph{environment} in effect at that point. The value +stored in the location to which a variable is bound is called the +variable's value. By abuse of terminology, the variable is sometimes +said to name the value or to be bound to the value. This is not quite +accurate, but confusion rarely results from this practice. + +@ignore todo +Define ``assigned'' and ``unassigned'' perhaps? +@end ignore + + +@ignore todo +In programs without side effects, one can safely pretend that the +variables are bound directly to the arguments. Or: +In programs without @code{set!}, one can safely pretend that the +@vindex @w{set!} +variable is bound directly to the value. +@end ignore + + +Certain expression types are used to create new kinds of syntax +and bind syntactic keywords to those new syntaxes, while other +expression types create new locations and bind variables to those +locations. These expression types are called @emph{binding constructs}. + +@cindex @w{binding construct} +Those that bind syntactic keywords are listed in section @ref{Macros}. +The most fundamental of the variable binding constructs is the +@samp{lambda} expression, because all other variable binding constructs +can be explained in terms of @samp{lambda} expressions. The other +variable binding constructs are @samp{let}, @samp{let*}, @samp{letrec}, +and @samp{do} expressions (see sections @pxref{Procedures}, @pxref{Binding constructs}, and +@pxref{Iteration}). + +@c Note: internal definitions not mentioned here. + +Like Algol and Pascal, and unlike most other dialects of Lisp +except for Common Lisp, Scheme is a statically scoped language with +block structure. To each place where an identifier is bound in a program +there corresponds a @dfn{region} of the program text within which +@cindex @w{region} +the binding is visible. The region is determined by the particular +binding construct that establishes the binding; if the binding is +established by a @samp{lambda} expression, for example, then its region +is the entire @samp{lambda} expression. Every mention of an identifier +refers to the binding of the identifier that established the +innermost of the regions containing the use. If there is no binding of +the identifier whose region contains the use, then the use refers to the +binding for the variable in the top level environment, if any +(chapters @pxref{Expressions} and @pxref{Standard procedures}); if there is no +binding for the identifier, +it is said to be @dfn{unbound}. +@cindex @w{top level environment} +@cindex @w{bound} +@cindex @w{unbound} + +@ignore todo +Mention that some implementations have multiple top level environments? +@end ignore + + +@ignore todo +Pitman sez: needs elaboration in case of @t{(let ...)} +@end ignore + + +@ignore todo +Pitman asks: say something about vars created after scheme starts? +@t{(define x 3) (define (f) x) (define (g) y) (define y 4)} +Clinger replies: The language was explicitly +designed to permit a view in which no variables are created after +Scheme starts. In files, you can scan out the definitions beforehand. +I think we're agreed on the principle that interactive use should +approximate that behavior as closely as possible, though we don't yet +agree on which programming environment provides the best approximation. +@end ignore + + +@node Disjointness of types, External representations, Variables; syntactic keywords; and regions, Basic concepts +@section Disjointness of types + + + +No object satisfies more than one of the following predicates: + + +@example + +boolean? pair? +symbol? number? +char? string? +vector? port? +procedure? + +@end example + + +These predicates define the types @emph{boolean}, @emph{pair}, @emph{symbol}, @emph{number}, @emph{char} (or @emph{character}), @emph{string}, @emph{vector}, @emph{port}, and @emph{procedure}. The empty list is a special +object of its own type; it satisfies none of the above predicates. + +@vindex symbol? +@vindex pair? +@vindex boolean? +@cindex @w{type} + +@vindex vector? +@vindex string? +@vindex char? +@vindex number? + +@cindex @w{empty list} +@vindex procedure? +@vindex port? + +Although there is a separate boolean type, +any Scheme value can be used as a boolean value for the purpose of a +conditional test. As explained in section @ref{Booleans}, all +values count as true in such a test except for @t{#f}. +@c and possibly the empty list. +@c The only value that is guaranteed to count as +@c false is \schfalse{}. It is explicitly unspecified whether the empty list +@c counts as true or as false. +This report uses the word ``true'' to refer to any +Scheme value except @t{#f}, and the word ``false'' to refer to +@t{#f}. +@cindex @w{false} +@cindex @w{true} + +@node External representations, Storage model, Disjointness of types, Basic concepts +@section External representations + + + +An important concept in Scheme (and Lisp) is that of the @emph{external +representation} of an object as a sequence of characters. For example, +an external representation of the integer 28 is the sequence of +characters ``@t{28}'', and an external representation of a list consisting +of the integers 8 and 13 is the sequence of characters ``@t{(8 13)}''. + +The external representation of an object is not necessarily unique. The +integer 28 also has representations ``@t{#e28.000}'' and ``@t{#x1c}'', and the +list in the previous paragraph also has the representations ``@t{( 08 13 +)}'' and ``@t{(8 .@: (13 .@: ()))}'' (see section @pxref{Pairs and lists}). + +Many objects have standard external representations, but some, such as +procedures, do not have standard representations (although particular +implementations may define representations for them). + +An external representation may be written in a program to obtain the +corresponding object (see @samp{quote}, section @pxref{Literal expressions}). + +External representations can also be used for input and output. The +procedure @samp{read} (section @pxref{Input}) parses external +representations, and the procedure @samp{write} (section @pxref{Output}) +generates them. Together, they provide an elegant and powerful +input/output facility. + +Note that the sequence of characters ``@t{(+ 2 6)}'' is @emph{not} an +external representation of the integer 8, even though it @emph{is} an +expression evaluating to the integer 8; rather, it is an external +representation of a three-element list, the elements of which are the symbol +@t{+} and the integers 2 and 6. Scheme's syntax has the property that +any sequence of characters that is an expression is also the external +representation of some object. This can lead to confusion, since it may +not be obvious out of context whether a given sequence of characters is +intended to denote data or program, but it is also a source of power, +since it facilitates writing programs such as interpreters and +compilers that treat programs as data (or vice versa). + +The syntax of external representations of various kinds of objects +accompanies the description of the primitives for manipulating the +objects in the appropriate sections of chapter @ref{Standard procedures}. + +@node Storage model, Proper tail recursion, External representations, Basic concepts +@section Storage model + + + +Variables and objects such as pairs, vectors, and strings implicitly +denote locations or sequences of locations. A string, for +@cindex @w{location} +example, denotes as many locations as there are characters in the string. +(These locations need not correspond to a full machine word.) A new value may be +stored into one of these locations using the @t{string-set!} procedure, but +the string continues to denote the same locations as before. + +An object fetched from a location, by a variable reference or by +a procedure such as @samp{car}, @samp{vector-ref}, or @samp{string-ref}, is +equivalent in the sense of @code{eqv?} +@c and \ide{eq?} ?? +(section @pxref{Equivalence predicates}) +@vindex @w{eqv?} +to the object last stored in the location before the fetch. + +Every location is marked to show whether it is in use. +No variable or object ever refers to a location that is not in use. +Whenever this report speaks of storage being allocated for a variable +or object, what is meant is that an appropriate number of locations are +chosen from the set of locations that are not in use, and the chosen +locations are marked to indicate that they are now in use before the variable +or object is made to denote them. + +In many systems it is desirable for constants (i.e. the values of +@cindex @w{constant} +literal expressions) to reside in read-only-memory. To express this, it is +convenient to imagine that every object that denotes locations is associated +with a flag telling whether that object is mutable or +@cindex @w{mutable} +immutable. In such systems literal constants and the strings +@cindex @w{immutable} +returned by @code{symbol->string} are immutable objects, while all objects +@vindex @w{symbol->string} +created by the other procedures listed in this report are mutable. It is an +error to attempt to store a new value into a location that is denoted by an +immutable object. + +@node Proper tail recursion, , Storage model, Basic concepts +@section Proper tail recursion + + + +Implementations of Scheme are required to be +@emph{properly tail-recursive}. +@cindex @w{proper tail recursion} +Procedure calls that occur in certain syntactic +contexts defined below are `tail calls'. A Scheme implementation is +properly tail-recursive if it supports an unbounded number of active +tail calls. A call is @emph{active} if the called procedure may still +return. Note that this includes calls that may be returned from either +by the current continuation or by continuations captured earlier by +@samp{call-with-current-continuation} that are later invoked. +In the absence of captured continuations, calls could +return at most once and the active calls would be those that had not +yet returned. +A formal definition of proper tail recursion can be found +in [propertailrecursion]. + + +@quotation +@emph{Rationale:} + +Intuitively, no space is needed for an active tail call because the +continuation that is used in the tail call has the same semantics as the +continuation passed to the procedure containing the call. Although an improper +implementation might use a new continuation in the call, a return +to this new continuation would be followed immediately by a return +to the continuation passed to the procedure. A properly tail-recursive +implementation returns to that continuation directly. + +Proper tail recursion was one of the central ideas in Steele and +Sussman's original version of Scheme. Their first Scheme interpreter +implemented both functions and actors. Control flow was expressed using +actors, which differed from functions in that they passed their results +on to another actor instead of returning to a caller. In the terminology +of this section, each actor finished with a tail call to another actor. + +Steele and Sussman later observed that in their interpreter the code +for dealing with actors was identical to that for functions and thus +there was no need to include both in the language. + +@end quotation + + +A @emph{tail call} is a procedure call that occurs +@cindex @w{tail call} +in a @emph{tail context}. Tail contexts are defined inductively. Note +that a tail context is always determined with respect to a particular lambda +expression. + + + +@itemize @bullet + +@item +The last expression within the body of a lambda expression, +shown as @r{<tail expression>} below, occurs in a tail context. + +@format +@t{(lambda <formals> + <definition>* <expression>* <tail expression>) +} + +@end format + + + +@item +If one of the following expressions is in a tail context, +then the subexpressions shown as <tail expression> are in a tail context. +These were derived from rules in the grammar given in +chapter @ref{Formal syntax and semantics} by replacing some occurrences of <expression> +with <tail expression>. Only those rules that contain tail contexts +are shown here. + + +@format +@t{(if <expression> <tail expression> <tail expression>) +(if <expression> <tail expression>) + +(cond <cond clause>+) +(cond <cond clause>* (else <tail sequence>)) + +(case <expression> + <case clause>+) +(case <expression> + <case clause>* + (else <tail sequence>)) + +(and <expression>* <tail expression>) +(or <expression>* <tail expression>) + +(let (<binding spec>*) <tail body>) +(let <variable> (<binding spec>*) <tail body>) +(let* (<binding spec>*) <tail body>) +(letrec (<binding spec>*) <tail body>) + +(let-syntax (<syntax spec>*) <tail body>) +(letrec-syntax (<syntax spec>*) <tail body>) + +(begin <tail sequence>) + +(do (<iteration spec>*) + (<test> <tail sequence>) + <expression>*) + +@r{where} + +<cond clause> --> (<test> <tail sequence>) +<case clause> --> ((<datum>*) <tail sequence>) + +<tail body> --> <definition>* <tail sequence> +<tail sequence> --> <expression>* <tail expression> +} + +@end format + + + +@item +If a @samp{cond} expression is in a tail context, and has a clause of +the form @samp{(@r{<expression1>} => @r{<expression2>})} +then the (implied) call to +the procedure that results from the evaluation of @r{<expression2>} is in a +tail context. @r{<expression2>} itself is not in a tail context. + + +@end itemize + + +Certain built-in procedures are also required to perform tail calls. +The first argument passed to @code{apply} and to +@vindex @w{apply} +@code{call-with-current-continuation}, and the second argument passed to +@vindex @w{call-with-current-continuation} +@code{call-with-values}, must be called via a tail call. +@vindex @w{call-with-values} +Similarly, @code{eval} must evaluate its argument as if it +@vindex @w{eval} +were in tail position within the @code{eval} procedure. +@vindex @w{eval} + +In the following example the only tail call is the call to @samp{f}. +None of the calls to @samp{g} or @samp{h} are tail calls. The reference to +@samp{x} is in a tail context, but it is not a call and thus is not a +tail call. + +@example + +(lambda () + (if (g) + (let ((x (h))) + x) + (and (g) (f)))) + +@end example + + + +@quotation +@emph{Note:} +Implementations are allowed, but not required, to +recognize that some non-tail calls, such as the call to @samp{h} +above, can be evaluated as though they were tail calls. +In the example above, the @samp{let} expression could be compiled +as a tail call to @samp{h}. (The possibility of @samp{h} returning +an unexpected number of values can be ignored, because in that +case the effect of the @samp{let} is explicitly unspecified and +implementation-dependent.) +@end quotation + + + +@c @include{expr} + +@c \vfill\eject +@node Expressions, Program structure, Basic concepts, top +@chapter Expressions + +@menu +* Primitive expression types:: +* Derived expression types:: +* Macros:: +@end menu + + + +@c \newcommand{\syntax}{{\em Syntax: }} +@c \newcommand{\semantics}{{\em Semantics: }} + +@c [Deleted for R5RS because of multiple-value returns. -RK] +@c A Scheme expression is a construct that returns a value, such as a +@c variable reference, literal, procedure call, or conditional. + +Expression types are categorized as @emph{primitive} or @emph{derived}. +Primitive expression types include variables and procedure calls. +Derived expression types are not semantically primitive, but can instead +be defined as macros. +With the exception of @samp{quasiquote}, whose macro definition is complex, +the derived expressions are classified as library features. +Suitable definitions are given in section @ref{Derived expression type}. + +@node Primitive expression types, Derived expression types, Expressions, Expressions +@section Primitive expression types + +@menu +* Variable references:: +* Literal expressions:: +* Procedure calls:: +* Procedures:: +* Conditionals:: +* Assignments:: +@end menu + + + +@node Variable references, Literal expressions, Primitive expression types, Primitive expression types +@subsection Variable references + + + +@deffn {syntax} @r{<variable>} + + +An expression consisting of a variable +@cindex @w{variable} +(section @pxref{Variables; syntactic keywords; and regions}) is a variable reference. The value of +the variable reference is the value stored in the location to which the +variable is bound. It is an error to reference an +unbound variable. +@cindex @w{unbound} + + +@format +@t{(define x 28) +x ==> 28 +} +@end format + +@end deffn + +@node Literal expressions, Procedure calls, Variable references, Primitive expression types +@subsection Literal expressions + + + + +@deffn {syntax} quote @r{<datum>} + +@deffnx {syntax} @t{'}@r{<datum>} + + +@deffnx {syntax} @r{<constant>} + + +@samp{(quote @r{<datum>})} evaluates to @r{<datum>}. +@cindex @w{'} +@r{<Datum>} +may be any external representation of a Scheme object (see +section @pxref{External representations}). This notation is used to include literal +constants in Scheme code. + + +@format +@t{ +(quote a) ==> a +(quote #(a b c)) ==> #(a b c) +(quote (+ 1 2)) ==> (+ 1 2) +} +@end format + + +@samp{(quote @r{<datum>})} may be abbreviated as +@t{'}@r{<datum>}. The two notations are equivalent in all +respects. + + +@format +@t{'a ==> a +'#(a b c) ==> #(a b c) +'() ==> () +'(+ 1 2) ==> (+ 1 2) +'(quote a) ==> (quote a) +''a ==> (quote a) +} +@end format + + +Numerical constants, string constants, character constants, and boolean +constants evaluate ``to themselves''; they need not be quoted. + + +@format +@t{'"abc" ==> "abc" +"abc" ==> "abc" +'145932 ==> 145932 +145932 ==> 145932 +'#t ==> #t +#t ==> #t +} +@end format + + +As noted in section @ref{Storage model}, it is an error to alter a constant +(i.e. the value of a literal expression) using a mutation procedure like +@samp{set-car!} or @samp{string-set!}. + +@end deffn + + +@node Procedure calls, Procedures, Literal expressions, Primitive expression types +@subsection Procedure calls + + + +@deffn {syntax} @r{<operator>} @r{<operand1>} @dots{}, + + +A procedure call is written by simply enclosing in parentheses +expressions for the procedure to be called and the arguments to be +passed to it. The operator and operand expressions are evaluated (in an +unspecified order) and the resulting procedure is passed the resulting +arguments. +@cindex @w{procedure call} +@cindex @w{call} + +@format +@t{ +(+ 3 4) ==> 7 +((if #f + *) 3 4) ==> 12 +} +@end format + + +A number of procedures are available as the values of variables in the +initial environment; for example, the addition and multiplication +procedures in the above examples are the values of the variables @samp{+} +and @samp{*}. New procedures are created by evaluating lambda expressions +(see section @pxref{Procedures}). +@ignore todo +At Friedman's request, flushed mention of other ways. +@end ignore + +@c or definitions (see section~\ref{define}). + +Procedure calls may return any number of values (see @code{values} in +@vindex @w{values} +section @pxref{Control features}). With the exception of @samp{values} +the procedures available in the initial environment return one +value or, for procedures such as @samp{apply}, pass on the values returned +by a call to one of their arguments. + +Procedure calls are also called @emph{combinations}. + +@cindex @w{combination} + + +@quotation +@emph{Note:} In contrast to other dialects of Lisp, the order of +evaluation is unspecified, and the operator expression and the operand +expressions are always evaluated with the same evaluation rules. +@end quotation + + + +@quotation +@emph{Note:} +Although the order of evaluation is otherwise unspecified, the effect of +any concurrent evaluation of the operator and operand expressions is +constrained to be consistent with some sequential order of evaluation. +The order of evaluation may be chosen differently for each procedure call. +@end quotation + + + +@quotation +@emph{Note:} In many dialects of Lisp, the empty combination, @t{()}, is a legitimate expression. In Scheme, combinations must have at +least one subexpression, so @t{()} is not a syntactically valid +expression. +@ignore todo +Dybvig: ``it should be obvious from the syntax.'' +@end ignore + +@end quotation + + +@ignore todo +Freeman: +I think an explanation as to why evaluation order is not specified +should be included. It should not include any reference to parallel +evaluation. Does any existing compiler generate better code because +the evaluation order is unspecified? Clinger: yes: T3, MacScheme v2, +probably MIT Scheme and Chez Scheme. But that's not the main reason +for leaving the order unspecified. +@end ignore + + +@end deffn + + +@node Procedures, Conditionals, Procedure calls, Primitive expression types +@subsection Procedures + + + + +@deffn {syntax} lambda @r{<formals>} @r{<body>} + +@emph{Syntax:} +@r{<Formals>} should be a formal arguments list as described below, +and @r{<body>} should be a sequence of one or more expressions. + +@emph{Semantics:} +A lambda expression evaluates to a procedure. The environment in +effect when the lambda expression was evaluated is remembered as part of the +procedure. When the procedure is later called with some actual +arguments, the environment in which the lambda expression was evaluated will +be extended by binding the variables in the formal argument list to +fresh locations, the corresponding actual argument values will be stored +in those locations, and the expressions in the body of the lambda expression +will be evaluated sequentially in the extended environment. +The result(s) of the last expression in the body will be returned as +the result(s) of the procedure call. + + +@format +@t{(lambda (x) (+ x x)) ==> @emph{}a procedure +((lambda (x) (+ x x)) 4) ==> 8 + +(define reverse-subtract + (lambda (x y) (- y x))) +(reverse-subtract 7 10) ==> 3 + +(define add4 + (let ((x 4)) + (lambda (y) (+ x y)))) +(add4 6) ==> 10 +} +@end format + + +@r{<Formals>} should have one of the following forms: + + + +@itemize @bullet + +@item +@t{(@r{<variable1>} @dots{},)}: +The procedure takes a fixed number of arguments; when the procedure is +called, the arguments will be stored in the bindings of the +corresponding variables. + +@item +@r{<variable>}: +The procedure takes any number of arguments; when the procedure is +called, the sequence of actual arguments is converted into a newly +allocated list, and the list is stored in the binding of the +@r{<variable>}. + +@item +@t{(@r{<variable1>} @dots{}, @r{<variable_n>} @b{.} +@r{<variable_n+1>})}: +If a space-delimited period precedes the last variable, then +the procedure takes n or more arguments, where n is the +number of formal arguments before the period (there must +be at least one). +The value stored in the binding of the last variable will be a +newly allocated +list of the actual arguments left over after all the other actual +arguments have been matched up against the other formal arguments. + +@end itemize + + +It is an error for a @r{<variable>} to appear more than once in +@r{<formals>}. + + +@format +@t{((lambda x x) 3 4 5 6) ==> (3 4 5 6) +((lambda (x y . z) z) + 3 4 5 6) ==> (5 6) +} +@end format + + +Each procedure created as the result of evaluating a lambda expression is +(conceptually) tagged +with a storage location, in order to make @code{eqv?} and +@vindex @w{eqv?} +@code{eq?} work on procedures (see section @pxref{Equivalence predicates}). +@vindex @w{eq?} + +@end deffn + + +@node Conditionals, Assignments, Procedures, Primitive expression types +@subsection Conditionals + + + +@deffn {syntax} if @r{<test>} @r{<consequent>} @r{<alternate>} +@deffnx {syntax} if @r{<test>} @r{<consequent>} +@c \/ if hyper = italic + +@emph{Syntax:} +@r{<Test>}, @r{<consequent>}, and @r{<alternate>} may be arbitrary +expressions. + +@emph{Semantics:} +An @samp{if} expression is evaluated as follows: first, +@r{<test>} is evaluated. If it yields a true value (see +@cindex @w{true} +section @pxref{Booleans}), then @r{<consequent>} is evaluated and +its value(s) is(are) returned. Otherwise @r{<alternate>} is evaluated and its +value(s) is(are) returned. If @r{<test>} yields a false value and no +@r{<alternate>} is specified, then the result of the expression is +unspecified. + + +@format +@t{(if (> 3 2) 'yes 'no) ==> yes +(if (> 2 3) 'yes 'no) ==> no +(if (> 3 2) + (- 3 2) + (+ 3 2)) ==> 1 +} +@end format + + +@end deffn + + +@node Assignments, , Conditionals, Primitive expression types +@subsection Assignments + + + + +@deffn {syntax} set! @r{<variable>} @r{<expression>} + +@r{<Expression>} is evaluated, and the resulting value is stored in +the location to which @r{<variable>} is bound. @r{<Variable>} must +be bound either in some region enclosing the @samp{set!} expression +@cindex @w{region} +or at top level. The result of the @samp{set!} expression is +unspecified. + + +@format +@t{(define x 2) +(+ x 1) ==> 3 +(set! x 4) ==> @emph{unspecified} +(+ x 1) ==> 5 +} +@end format + + +@end deffn + + +@node Derived expression types, Macros, Primitive expression types, Expressions +@section Derived expression types + +@menu +* Conditional:: +* Binding constructs:: +* Sequencing:: +* Iteration:: +* Delayed evaluation:: +* Quasiquotation:: +@end menu + + + +The constructs in this section are hygienic, as discussed in +section @ref{Macros}. +For reference purposes, section @ref{Derived expression type} gives macro definitions +that will convert most of the constructs described in this section +into the primitive constructs described in the previous section. + +@ignore todo +Mention that no definition of backquote is provided? +@end ignore + + +@node Conditional, Binding constructs, Derived expression types, Derived expression types +@subsection Conditionals + + + +@deffn {library syntax} cond <clause1> <clause2> @dots{}, + +@emph{Syntax:} +Each @r{<clause>} should be of the form + +@format +@t{(@r{<test>} @r{<expression1>} @dots{},) +} +@end format + +where @r{<test>} is any expression. Alternatively, a @r{<clause>} may be +of the form + +@format +@t{(@r{<test>} => @r{<expression>}) +} +@end format + +The last @r{<clause>} may be +an ``else clause,'' which has the form + +@format +@t{(else @r{<expression1>} @r{<expression2>} @dots{},)@r{.} +} +@end format + + +@cindex @w{else} + +@cindex @w{=>} + +@emph{Semantics:} +A @samp{cond} expression is evaluated by evaluating the @r{<test>} +expressions of successive @r{<clause>}s in order until one of them +evaluates to a true value (see +@cindex @w{true} +section @pxref{Booleans}). When a @r{<test>} evaluates to a true +value, then the remaining @r{<expression>}s in its @r{<clause>} are +evaluated in order, and the result(s) of the last @r{<expression>} in the +@r{<clause>} is(are) returned as the result(s) of the entire @samp{cond} +expression. If the selected @r{<clause>} contains only the +@r{<test>} and no @r{<expression>}s, then the value of the +@r{<test>} is returned as the result. If the selected @r{<clause>} uses the +@code{=>} alternate form, then the @r{<expression>} is evaluated. +@vindex @w{=>} +Its value must be a procedure that accepts one argument; this procedure is then +called on the value of the @r{<test>} and the value(s) returned by this +procedure is(are) returned by the @samp{cond} expression. +If all @r{<test>}s evaluate +to false values, and there is no else clause, then the result of +the conditional expression is unspecified; if there is an else +clause, then its @r{<expression>}s are evaluated, and the value(s) of +the last one is(are) returned. + + +@format +@t{(cond ((> 3 2) 'greater) + ((< 3 2) 'less)) ==> greater + +(cond ((> 3 3) 'greater) + ((< 3 3) 'less) + (else 'equal)) ==> equal + +(cond ((assv 'b '((a 1) (b 2))) => cadr) + (else #f)) ==> 2 +} +@end format + + + +@end deffn + + + +@deffn {library syntax} case @r{<key>} <clause1> <clause2> @dots{}, + +@emph{Syntax:} +@r{<Key>} may be any expression. Each @r{<clause>} should have +the form + +@format +@t{((@r{<datum1>} @dots{},) @r{<expression1>} @r{<expression2>} @dots{},)@r{,} +} +@end format + +where each @r{<datum>} is an external representation of some object. +All the @r{<datum>}s must be distinct. +The last @r{<clause>} may be an ``else clause,'' which has the form + +@format +@t{(else @r{<expression1>} @r{<expression2>} @dots{},)@r{.} +} +@end format + + +@vindex else + +@emph{Semantics:} +A @samp{case} expression is evaluated as follows. @r{<Key>} is +evaluated and its result is compared against each @r{<datum>}. If the +result of evaluating @r{<key>} is equivalent (in the sense of +@samp{eqv?}; see section @pxref{Equivalence predicates}) to a @r{<datum>}, then the +expressions in the corresponding @r{<clause>} are evaluated from left +to right and the result(s) of the last expression in the @r{<clause>} is(are) +returned as the result(s) of the @samp{case} expression. If the result of +evaluating @r{<key>} is different from every @r{<datum>}, then if +there is an else clause its expressions are evaluated and the +result(s) of the last is(are) the result(s) of the @samp{case} expression; +otherwise the result of the @samp{case} expression is unspecified. + + +@format +@t{(case (* 2 3) + ((2 3 5 7) 'prime) + ((1 4 6 8 9) 'composite)) ==> composite +(case (car '(c d)) + ((a) 'a) + ((b) 'b)) ==> @emph{unspecified} +(case (car '(c d)) + ((a e i o u) 'vowel) + ((w y) 'semivowel) + (else 'consonant)) ==> consonant +} +@end format + + +@end deffn + + + +@deffn {library syntax} and <test1> @dots{}, + +The @r{<test>} expressions are evaluated from left to right, and the +value of the first expression that evaluates to a false value (see +section @pxref{Booleans}) is returned. Any remaining expressions +are not evaluated. If all the expressions evaluate to true values, the +value of the last expression is returned. If there are no expressions +then @t{#t} is returned. + + +@format +@t{(and (= 2 2) (> 2 1)) ==> #t +(and (= 2 2) (< 2 1)) ==> #f +(and 1 2 'c '(f g)) ==> (f g) +(and) ==> #t +} +@end format + + +@end deffn + + + +@deffn {library syntax} or <test1> @dots{}, + +The @r{<test>} expressions are evaluated from left to right, and the value of the +first expression that evaluates to a true value (see +section @pxref{Booleans}) is returned. Any remaining expressions +are not evaluated. If all expressions evaluate to false values, the +value of the last expression is returned. If there are no +expressions then @t{#f} is returned. + + +@format +@t{(or (= 2 2) (> 2 1)) ==> #t +(or (= 2 2) (< 2 1)) ==> #t +(or #f #f #f) ==> #f +(or (memq 'b '(a b c)) + (/ 3 0)) ==> (b c) +} +@end format + + +@end deffn + + +@node Binding constructs, Sequencing, Conditional, Derived expression types +@subsection Binding constructs + + +The three binding constructs @samp{let}, @samp{let*}, and @samp{letrec} +give Scheme a block structure, like Algol 60. The syntax of the three +constructs is identical, but they differ in the regions they establish +@cindex @w{region} +for their variable bindings. In a @samp{let} expression, the initial +values are computed before any of the variables become bound; in a +@samp{let*} expression, the bindings and evaluations are performed +sequentially; while in a @samp{letrec} expression, all the bindings are in +effect while their initial values are being computed, thus allowing +mutually recursive definitions. + + +@deffn {library syntax} let @r{<bindings>} @r{<body>} + +@emph{Syntax:} +@r{<Bindings>} should have the form + +@format +@t{((@r{<variable1>} @r{<init1>}) @dots{},)@r{,} +} +@end format + +where each @r{<init>} is an expression, and @r{<body>} should be a +sequence of one or more expressions. It is +an error for a @r{<variable>} to appear more than once in the list of variables +being bound. + +@emph{Semantics:} +The @r{<init>}s are evaluated in the current environment (in some +unspecified order), the @r{<variable>}s are bound to fresh locations +holding the results, the @r{<body>} is evaluated in the extended +environment, and the value(s) of the last expression of @r{<body>} +is(are) returned. Each binding of a @r{<variable>} has @r{<body>} as its +region. +@cindex @w{region} + + +@format +@t{(let ((x 2) (y 3)) + (* x y)) ==> 6 + +(let ((x 2) (y 3)) + (let ((x 7) + (z (+ x y))) + (* z x))) ==> 35 +} +@end format + + +See also named @samp{let}, section @ref{Iteration}. + +@end deffn + + + +@deffn {library syntax} let* @r{<bindings>} @r{<body>} + + +@emph{Syntax:} +@r{<Bindings>} should have the form + +@format +@t{((@r{<variable1>} @r{<init1>}) @dots{},)@r{,} +} +@end format + +and @r{<body>} should be a sequence of +one or more expressions. + +@emph{Semantics:} +@samp{Let*} is similar to @samp{let}, but the bindings are performed +sequentially from left to right, and the region of a binding indicated +@cindex @w{region} +by @samp{(@r{<variable>} @r{<init>})} is that part of the @samp{let*} +expression to the right of the binding. Thus the second binding is done +in an environment in which the first binding is visible, and so on. + + +@format +@t{(let ((x 2) (y 3)) + (let* ((x 7) + (z (+ x y))) + (* z x))) ==> 70 +} +@end format + + +@end deffn + + + +@deffn {library syntax} letrec @r{<bindings>} @r{<body>} + +@emph{Syntax:} +@r{<Bindings>} should have the form + +@format +@t{((@r{<variable1>} @r{<init1>}) @dots{},)@r{,} +} +@end format + +and @r{<body>} should be a sequence of +one or more expressions. It is an error for a @r{<variable>} to appear more +than once in the list of variables being bound. + +@emph{Semantics:} +The @r{<variable>}s are bound to fresh locations holding undefined +values, the @r{<init>}s are evaluated in the resulting environment (in +some unspecified order), each @r{<variable>} is assigned to the result +of the corresponding @r{<init>}, the @r{<body>} is evaluated in the +resulting environment, and the value(s) of the last expression in +@r{<body>} is(are) returned. Each binding of a @r{<variable>} has the +entire @samp{letrec} expression as its region, making it possible to +@cindex @w{region} +define mutually recursive procedures. + + +@format +@t{(letrec ((even? + (lambda (n) + (if (zero? n) + #t + (odd? (- n 1))))) + (odd? + (lambda (n) + (if (zero? n) + #f + (even? (- n 1)))))) + (even? 88)) + ==> #t +} +@end format + + +One restriction on @samp{letrec} is very important: it must be possible +to evaluate each @r{<init>} without assigning or referring to the value of any +@r{<variable>}. If this restriction is violated, then it is an error. The +restriction is necessary because Scheme passes arguments by value rather than by +name. In the most common uses of @samp{letrec}, all the @r{<init>}s are +lambda expressions and the restriction is satisfied automatically. + +@c \todo{use or uses? --- Jinx.} + +@end deffn + + +@node Sequencing, Iteration, Binding constructs, Derived expression types +@subsection Sequencing + + + +@deffn {library syntax} begin <expression1> <expression2> @dots{}, + +The @r{<expression>}s are evaluated sequentially from left to right, +and the value(s) of the last @r{<expression>} is(are) returned. This +expression type is used to sequence side effects such as input and +output. + + +@format +@t{(define x 0) + +(begin (set! x 5) + (+ x 1)) ==> 6 + +(begin (display "4 plus 1 equals ") + (display (+ 4 1))) ==> @emph{unspecified} + @emph{and prints} 4 plus 1 equals 5 +} +@end format + + +@end deffn + + +@node Iteration, Delayed evaluation, Sequencing, Derived expression types +@subsection Iteration + +@c \unsection + + +@noindent + +@deffn {library syntax} do ((@r{<variable1>} @r{<init1>} @r{<step1>}) @dots{}) (@r{<test>} @r{<expression>} @dots{}) @r{<command>} @dots{} +@cindex @w{do} + +@samp{Do} is an iteration construct. It specifies a set of variables to +be bound, how they are to be initialized at the start, and how they are +to be updated on each iteration. When a termination condition is met, +the loop exits after evaluating the @r{<expression>}s. + +@samp{Do} expressions are evaluated as follows: +The @r{<init>} expressions are evaluated (in some unspecified order), +the @r{<variable>}s are bound to fresh locations, the results of the +@r{<init>} expressions are stored in the bindings of the +@r{<variable>}s, and then the iteration phase begins. + +Each iteration begins by evaluating @r{<test>}; if the result is +false (see section @pxref{Booleans}), then the @r{<command>} +expressions are evaluated in order for effect, the @r{<step>} +expressions are evaluated in some unspecified order, the +@r{<variable>}s are bound to fresh locations, the results of the +@r{<step>}s are stored in the bindings of the +@r{<variable>}s, and the next iteration begins. + +If @r{<test>} evaluates to a true value, then the +@r{<expression>}s are evaluated from left to right and the value(s) of +the last @r{<expression>} is(are) returned. If no @r{<expression>}s +are present, then the value of the @samp{do} expression is unspecified. + +The region of the binding of a @r{<variable>} +@cindex @w{region} +consists of the entire @samp{do} expression except for the @r{<init>}s. +It is an error for a @r{<variable>} to appear more than once in the +list of @samp{do} variables. + +A @r{<step>} may be omitted, in which case the effect is the +same as if @samp{(@r{<variable>} @r{<init>} @r{<variable>})} had +been written instead of @samp{(@r{<variable>} @r{<init>})}. + + +@format +@t{(do ((vec (make-vector 5)) + (i 0 (+ i 1))) + ((= i 5) vec) + (vector-set! vec i i)) ==> #(0 1 2 3 4) + +(let ((x '(1 3 5 7 9))) + (do ((x x (cdr x)) + (sum 0 (+ sum (car x)))) + ((null? x) sum))) ==> 25 +} +@end format + + +@c \end{entry} +@end deffn + + +@deffn {library syntax} let @r{<variable>} @r{<bindings>} @r{<body>} + + +``Named @samp{let}'' is a variant on the syntax of @code{let} which provides +@vindex @w{let} +a more general looping construct than @samp{do} and may also be used to express +recursions. +It has the same syntax and semantics as ordinary @samp{let} +except that @r{<variable>} is bound within @r{<body>} to a procedure +whose formal arguments are the bound variables and whose body is +@r{<body>}. Thus the execution of @r{<body>} may be repeated by +invoking the procedure named by @r{<variable>}. + +@c | <-- right margin + +@format +@t{(let loop ((numbers '(3 -2 1 6 -5)) + (nonneg '()) + (neg '())) + (cond ((null? numbers) (list nonneg neg)) + ((>= (car numbers) 0) + (loop (cdr numbers) + (cons (car numbers) nonneg) + neg)) + ((< (car numbers) 0) + (loop (cdr numbers) + nonneg + (cons (car numbers) neg))))) + ==> ((6 1 3) (-5 -2)) +} +@end format + + +@end deffn + + +@node Delayed evaluation, Quasiquotation, Iteration, Derived expression types +@subsection Delayed evaluation + + + +@deffn {library syntax} delay @r{<expression>} + +@ignore todo +Fix. +@end ignore + + +The @samp{delay} construct is used together with the procedure @code{force} to +@vindex @w{force} +implement @dfn{lazy evaluation} or @dfn{call by need}. +@cindex @w{call by need} +@cindex @w{lazy evaluation} +@t{(delay @r{<expression>})} returns an object called a +@dfn{promise} which at some point in the future may be asked (by +@cindex @w{promise} +the @samp{force} procedure) +@ignore todo +Bartley's white lie; OK? +@end ignore + to evaluate +@r{<expression>}, and deliver the resulting value. +The effect of @r{<expression>} returning multiple values +is unspecified. + +See the description of @samp{force} (section @pxref{Control features}) for a +more complete description of @samp{delay}. + +@end deffn + + +@node Quasiquotation, , Delayed evaluation, Derived expression types +@subsection Quasiquotation + + + + +@deffn {syntax} quasiquote @r{<qq template>} + +@deffnx {syntax} @t{`}@r{<qq template>} + + +``Backquote'' or ``quasiquote'' expressions are useful +@cindex @w{backquote} +for constructing a list or vector structure when most but not all of the +desired structure is known in advance. If no +commas appear within the @r{<qq template>}, the result of +@cindex @w{comma} +evaluating +@t{`}@r{<qq template>} is equivalent to the result of evaluating +@t{'}@r{<qq template>}. If a comma appears within the +@cindex @w{,} +@r{<qq template>}, however, the expression following the comma is +evaluated (``unquoted'') and its result is inserted into the structure +instead of the comma and the expression. If a comma appears followed +immediately by an at-sign (@@), then the following +@cindex @w{,@@} +expression must evaluate to a list; the opening and closing parentheses +of the list are then ``stripped away'' and the elements of the list are +inserted in place of the comma at-sign expression sequence. A comma +at-sign should only appear within a list or vector @r{<qq template>}. + +@c struck: "(in the sense of {\cf equal?})" after "equivalent" + + +@format +@t{`(list ,(+ 1 2) 4) ==> (list 3 4) +(let ((name 'a)) `(list ,name ',name)) + ==> (list a (quote a)) +`(a ,(+ 1 2) ,@@(map abs '(4 -5 6)) b) + ==> (a 3 4 5 6 b) +`((@samp{foo} ,(- 10 3)) ,@@(cdr '(c)) . ,(car '(cons))) + ==> ((foo 7) . cons) +`#(10 5 ,(sqrt 4) ,@@(map sqrt '(16 9)) 8) + ==> #(10 5 2 4 3 8) +} +@end format + + +Quasiquote forms may be nested. Substitutions are made only for +unquoted components appearing at the same nesting level +as the outermost backquote. The nesting level increases by one inside +each successive quasiquotation, and decreases by one inside each +unquotation. + + +@format +@t{`(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f) + ==> (a `(b ,(+ 1 2) ,(foo 4 d) e) f) +(let ((name1 'x) + (name2 'y)) + `(a `(b ,,name1 ,',name2 d) e)) + ==> (a `(b ,x ,'y d) e) +} +@end format + + +The two notations + @t{`}@r{<qq template>} and @t{(quasiquote @r{<qq template>})} + are identical in all respects. + @samp{,@r{<expression>}} is identical to @samp{(unquote @r{<expression>})}, + and + @samp{,@@@r{<expression>}} is identical to @samp{(unquote-splicing @r{<expression>})}. +The external syntax generated by @code{write} for two-element lists whose +@vindex @w{write} +car is one of these symbols may vary between implementations. + +@cindex @w{`} + + +@format +@t{(quasiquote (list (unquote (+ 1 2)) 4)) + ==> (list 3 4) +'(quasiquote (list (unquote (+ 1 2)) 4)) + ==> `(list ,(+ 1 2) 4) + @emph{}i.e., (quasiquote (list (unquote (+ 1 2)) 4)) +} +@end format + + +Unpredictable behavior can result if any of the symbols +@code{quasiquote}, @code{unquote}, or @code{unquote-splicing} appear in +@vindex @w{unquote-splicing} +@vindex @w{unquote} +@vindex @w{quasiquote} +positions within a @r{<qq template>} otherwise than as described above. + +@end deffn + +@node Macros, , Derived expression types, Expressions +@section Macros + +@menu +* Binding constructs for syntactic keywords:: +* Pattern language:: +@end menu + + + +Scheme programs can define and use new derived expression types, + called @emph{macros}. +@cindex @w{macro} +Program-defined expression types have the syntax + +@example + +(@r{<keyword>} @r{<datum>} ...) + +@end example + +where @r{<keyword>} is an identifier that uniquely determines the +expression type. This identifier is called the @emph{syntactic +keyword}, or simply @emph{keyword}, of the macro. The +@cindex @w{macro keyword} +@cindex @w{keyword} +@cindex @w{syntactic keyword} +number of the @r{<datum>}s, and their syntax, depends on the +expression type. + +Each instance of a macro is called a @emph{use} +@cindex @w{macro use} +of the macro. +The set of rules that specifies +how a use of a macro is transcribed into a more primitive expression +is called the @emph{transformer} +@cindex @w{macro transformer} +of the macro. + +The macro definition facility consists of two parts: + + + +@itemize @bullet + +@item +A set of expressions used to establish that certain identifiers +are macro keywords, associate them with macro transformers, and control +the scope within which a macro is defined, and + +@item +a pattern language for specifying macro transformers. + +@end itemize + + +The syntactic keyword of a macro may shadow variable bindings, and local +variable bindings may shadow keyword bindings. All macros +@cindex @w{keyword} +defined using the pattern language are ``hygienic'' and ``referentially +transparent'' and thus preserve Scheme's lexical scoping [Kohlbecker86], [ +hygienic], [Bawden88], [macrosthatwork], [syntacticabstraction]: + +@cindex @w{hygienic} + +@cindex @w{referentially transparent} + + + + +@itemize @bullet + + +@item +If a macro transformer inserts a binding for an identifier +(variable or keyword), the identifier will in effect be renamed +throughout its scope to avoid conflicts with other identifiers. +Note that a @code{define} at top level may or may not introduce a binding; +see section @ref{Definitions}. + +@item +If a macro transformer inserts a free reference to an +identifier, the reference refers to the binding that was visible +where the transformer was specified, regardless of any local +bindings that may surround the use of the macro. + + +@end itemize + +@vindex @w{define} + +@c The low-level facility permits non-hygienic macros to be written, +@c and may be used to implement the high-level pattern language. + +@c The fourth section describes some features that would make the +@c low-level macro facility easier to use directly. + +@node Binding constructs for syntactic keywords, Pattern language, Macros, Macros +@subsection Binding constructs for syntactic keywords + + + +@samp{Let-syntax} and @samp{letrec-syntax} are +analogous to @samp{let} and @samp{letrec}, but they bind +syntactic keywords to macro transformers instead of binding variables +to locations that contain values. Syntactic keywords may also be +bound at top level; see section @ref{Syntax definitions}. + + +@deffn {syntax} let-syntax @r{<bindings>} @r{<body>} + +@emph{Syntax:} +@r{<Bindings>} should have the form + +@format +@t{((@r{<keyword>} @r{<transformer spec>}) @dots{},) +} +@end format + +Each @r{<keyword>} is an identifier, +each @r{<transformer spec>} is an instance of @samp{syntax-rules}, and +@r{<body>} should be a sequence of one or more expressions. It is an error +for a @r{<keyword>} to appear more than once in the list of keywords +being bound. + +@emph{Semantics:} +The @r{<body>} is expanded in the syntactic environment +obtained by extending the syntactic environment of the +@samp{let-syntax} expression with macros whose keywords are +the @r{<keyword>}s, bound to the specified transformers. +Each binding of a @r{<keyword>} has @r{<body>} as its region. + + +@format +@t{(let-syntax ((when (syntax-rules () + ((when test stmt1 stmt2 ...) + (if test + (begin stmt1 + stmt2 ...)))))) + (let ((if #t)) + (when if (set! if 'now)) + if)) ==> now + +(let ((x 'outer)) + (let-syntax ((m (syntax-rules () ((m) x)))) + (let ((x 'inner)) + (m)))) ==> outer +} +@end format + + +@end deffn + + +@deffn {syntax} letrec-syntax @r{<bindings>} @r{<body>} + +@emph{Syntax:} +Same as for @samp{let-syntax}. + +@emph{Semantics:} + The @r{<body>} is expanded in the syntactic environment obtained by +extending the syntactic environment of the @samp{letrec-syntax} +expression with macros whose keywords are the +@r{<keyword>}s, bound to the specified transformers. +Each binding of a @r{<keyword>} has the @r{<bindings>} +as well as the @r{<body>} within its region, +so the transformers can +transcribe expressions into uses of the macros +introduced by the @samp{letrec-syntax} expression. + + +@format +@t{(letrec-syntax + ((my-or (syntax-rules () + ((my-or) #f) + ((my-or e) e) + ((my-or e1 e2 ...) + (let ((temp e1)) + (if temp + temp + (my-or e2 ...))))))) + (let ((x #f) + (y 7) + (temp 8) + (let odd?) + (if even?)) + (my-or x + (let temp) + (if y) + y))) ==> 7 +} +@end format + + +@end deffn + +@node Pattern language, , Binding constructs for syntactic keywords, Macros +@subsection Pattern language + + + +A @r{<transformer spec>} has the following form: + + +@deffn {} syntax-rules @r{<literals>} @r{<syntax rule>} @dots{}, + +@emph{Syntax:} +@r{<Literals>} is a list of identifiers and each @r{<syntax rule>} +should be of the form + +@format +@t{(@r{<pattern>} @r{<template>}) +} +@end format + +The @r{<pattern>} in a @r{<syntax rule>} is a list @r{<pattern>} +that begins with the keyword for the macro. + +A @r{<pattern>} is either an identifier, a constant, or one of the +following + +@format +@t{(@r{<pattern>} @dots{}) +(@r{<pattern>} @r{<pattern>} @dots{} . @r{<pattern>}) +(@r{<pattern>} @dots{} @r{<pattern>} @r{<ellipsis>}) +#(@r{<pattern>} @dots{}) +#(@r{<pattern>} @dots{} @r{<pattern>} @r{<ellipsis>}) +} +@end format + +and a template is either an identifier, a constant, or one of the following + +@format +@t{(@r{<element>} @dots{}) +(@r{<element>} @r{<element>} @dots{} . @r{<template>}) +#(@r{<element>} @dots{}) +} +@end format + +where an @r{<element>} is a @r{<template>} optionally +followed by an @r{<ellipsis>} and +an @r{<ellipsis>} is the identifier ``@samp{...}'' (which cannot be used as +an identifier in either a template or a pattern). +@vindex ... + +@emph{Semantics:} An instance of @samp{syntax-rules} produces a new macro +transformer by specifying a sequence of hygienic rewrite rules. A use +of a macro whose keyword is associated with a transformer specified by +@samp{syntax-rules} is matched against the patterns contained in the +@r{<syntax rule>}s, beginning with the leftmost @r{<syntax rule>}. +When a match is found, the macro use is transcribed hygienically +according to the template. + +An identifier that appears in the pattern of a @r{<syntax rule>} is +a @emph{pattern variable}, unless it is the keyword that begins the pattern, +is listed in @r{<literals>}, or is the identifier ``@samp{...}''. +Pattern variables match arbitrary input elements and +are used to refer to elements of the input in the template. It is an +error for the same pattern variable to appear more than once in a +@r{<pattern>}. + +The keyword at the beginning of the pattern in a +@r{<syntax rule>} is not involved in the matching and +is not considered a pattern variable or literal identifier. + + +@quotation +@emph{Rationale:} +The scope of the keyword is determined by the expression or syntax +definition that binds it to the associated macro transformer. +If the keyword were a pattern variable or literal +identifier, then +the template that follows the pattern would be within its scope +regardless of whether the keyword were bound by @samp{let-syntax} +or by @samp{letrec-syntax}. +@end quotation + + +Identifiers that appear in @r{<literals>} are interpreted as literal +identifiers to be matched against corresponding subforms of the input. +A subform +in the input matches a literal identifier if and only if it is an +identifier +and either both its occurrence in the macro expression and its +occurrence in the macro definition have the same lexical binding, or +the two identifiers are equal and both have no lexical binding. + +@c [Bill Rozas suggested the term "noise word" for these literal +@c identifiers, but in their most interesting uses, such as a setf +@c macro, they aren't noise words at all. -- Will] + +A subpattern followed by @samp{...} can match zero or more elements of the +input. It is an error for @samp{...} to appear in @r{<literals>}. +Within a pattern the identifier @samp{...} must follow the last element of +a nonempty sequence of subpatterns. + +More formally, an input form F matches a pattern P if and only if: + + + +@itemize @bullet + +@item +P is a non-literal identifier; or + +@item +P is a literal identifier and F is an identifier with the same +binding; or + +@item +P is a list @samp{(P_1 @dots{} P_n)} and F is a +list of n +forms that match P_1 through P_n, respectively; or + +@item +P is an improper list +@samp{(P_1 P_2 @dots{} P_n . P_n+1)} +and F is a list or +improper list of n or more forms that match P_1 through P_n, +respectively, and whose nth ``cdr'' matches P_n+1; or + +@item +P is of the form +@samp{(P_1 @dots{} P_n P_n+1 <ellipsis>)} +where <ellipsis> is the identifier @samp{...} +and F is +a proper list of at least n forms, the first n of which match +P_1 through P_n, respectively, and each remaining element of F +matches P_n+1; or + +@item +P is a vector of the form @samp{#(P_1 @dots{} P_n)} +and F is a vector +of n forms that match P_1 through P_n; or + +@item +P is of the form +@samp{#(P_1 @dots{} P_n P_n+1 <ellipsis>)} +where <ellipsis> is the identifier @samp{...} +and F is a vector of n +or more forms the first n of which match +P_1 through P_n, respectively, and each remaining element of F +matches P_n+1; or + +@item +P is a datum and F is equal to P in the sense of +the @samp{equal?} procedure. + +@end itemize + + +It is an error to use a macro keyword, within the scope of its +binding, in an expression that does not match any of the patterns. + +When a macro use is transcribed according to the template of the +matching @r{<syntax rule>}, pattern variables that occur in the +template are replaced by the subforms they match in the input. +Pattern variables that occur in subpatterns followed by one or more +instances of the identifier +@samp{...} are allowed only in subtemplates that are +followed by as many instances of @samp{...}. +They are replaced in the +output by all of the subforms they match in the input, distributed as +indicated. It is an error if the output cannot be built up as +specified. + +@c %% This description of output construction is very vague. It should +@c %% probably be formalized, but that is not easy... + +Identifiers that appear in the template but are not pattern variables +or the identifier +@samp{...} are inserted into the output as literal identifiers. If a +literal identifier is inserted as a free identifier then it refers to the +binding of that identifier within whose scope the instance of +@samp{syntax-rules} appears. +If a literal identifier is inserted as a bound identifier then it is +in effect renamed to prevent inadvertent captures of free identifiers. + +As an example, if @code{let} and @code{cond} are defined as in +@vindex @w{cond} +@vindex @w{let} +section @ref{Derived expression type} then they are hygienic (as required) and +the following is not an error. + + +@format +@t{(let ((=> #f)) + (cond (#t => 'ok))) ==> ok +} +@end format + + +The macro transformer for @samp{cond} recognizes @samp{=>} +as a local variable, and hence an expression, and not as the +top-level identifier @samp{=>}, which the macro transformer treats +as a syntactic keyword. Thus the example expands into + + +@format +@t{(let ((=> #f)) + (if #t (begin => 'ok))) +} +@end format + + +instead of + + +@format +@t{(let ((=> #f)) + (let ((temp #t)) + (if temp ('ok temp)))) +} +@end format + + +which would result in an invalid procedure call. + +@end deffn + + +@page + +@c @include{prog} +@node Program structure, Standard procedures, Expressions, top +@chapter Program structure + +@menu +* Programs:: +* Definitions:: +* Syntax definitions:: +@end menu + + + +@node Programs, Definitions, Program structure, Program structure +@section Programs + + +A Scheme program consists of a sequence of expressions, definitions, +and syntax definitions. +Expressions are described in chapter @ref{Expressions}; +definitions and syntax definitions are the subject of the rest of the +present chapter. + +Programs are typically stored in files or entered interactively to a +running Scheme system, although other paradigms are possible; +questions of user interface lie outside the scope of this report. +(Indeed, Scheme would still be useful as a notation for expressing +computational methods even in the absence of a mechanical +implementation.) + +Definitions and syntax definitions occurring at the top level of a program +can be interpreted +declaratively. +They cause bindings to be created in the top level +environment or modify the value of existing top-level bindings. +Expressions occurring at the top level of a program are +interpreted imperatively; they are executed in order when the program is +invoked or loaded, and typically perform some kind of initialization. + +At the top level of a program @t{(begin @r{<form1>} @dots{},)} is +equivalent to the sequence of expressions, definitions, and syntax definitions +that form the body of the @code{begin}. +@vindex @w{begin} + +@ignore todo +Cromarty, etc.: disclaimer about top level? +@end ignore + + +@node Definitions, Syntax definitions, Programs, Program structure +@section Definitions + +@menu +* Top level definitions:: +* Internal definitions:: +@end menu + + + +Definitions are valid in some, but not all, contexts where expressions +are allowed. They are valid only at the top level of a @r{<program>} +and at the beginning of a @r{<body>}. + +@cindex @w{definition} + +A definition should have one of the following forms: +@cindex @w{define} + + + +@itemize @bullet + + +@item @t{(define @r{<variable>} @r{<expression>})} + +@item @t{(define (@r{<variable>} @r{<formals>}) @r{<body>})} + +@r{<Formals>} should be either a +sequence of zero or more variables, or a sequence of one or more +variables followed by a space-delimited period and another variable (as +in a lambda expression). This form is equivalent to + +@example + +(define @r{<variable>} + (lambda (@r{<formals>}) @r{<body>}))@r{.} + +@end example + + +@item @t{(define (@r{<variable>} .@: @r{<formal>}) @r{<body>})} + +@r{<Formal>} should be a single +variable. This form is equivalent to + +@example + +(define @r{<variable>} + (lambda @r{<formal>} @r{<body>}))@r{.} + +@end example + + + +@end itemize + + +@node Top level definitions, Internal definitions, Definitions, Definitions +@subsection Top level definitions + + +At the top level of a program, a definition + +@example + +(define @r{<variable>} @r{<expression>}) + +@end example + +has essentially the same effect as the assignment expression + +@example + +(set! @r{<variable>} @r{<expression>}) + +@end example + +if @r{<variable>} is bound. If @r{<variable>} is not bound, +however, then the definition will bind @r{<variable>} to a new +location before performing the assignment, whereas it would be an error +to perform a @samp{set!} on an unbound variable. +@cindex @w{unbound} + + +@example + +(define add3 + (lambda (x) (+ x 3))) +(add3 3) ==> 6 +(define first car) +(first '(1 2)) ==> 1 + +@end example + + +Some implementations of Scheme use an initial environment in +which all possible variables are bound to locations, most of +which contain undefined values. Top level definitions in +such an implementation are truly equivalent to assignments. + +@ignore todo +Rozas: equal time for opposition semantics? +@end ignore + + + +@node Internal definitions, , Top level definitions, Definitions +@subsection Internal definitions + + + +Definitions may occur at the +beginning of a @r{<body>} (that is, the body of a @code{lambda}, +@vindex @w{lambda} +@code{let}, @code{let*}, @code{letrec}, @code{let-syntax}, or @code{letrec-syntax} +@vindex @w{letrec-syntax} +@vindex @w{let-syntax} +@vindex @w{letrec} +@vindex @w{let*} +@vindex @w{let} +expression or that of a definition of an appropriate form). +Such definitions are known as @emph{internal definitions} as opposed to the top level definitions described above. +@cindex @w{internal definition} +The variable defined by an internal definition is local to the +@r{<body>}. That is, @r{<variable>} is bound rather than assigned, +and the region of the binding is the entire @r{<body>}. For example, + + +@example + +(let ((x 5)) + (define foo (lambda (y) (bar x y))) + (define bar (lambda (a b) (+ (* a b) a))) + (foo (+ x 3))) ==> 45 + +@end example + + +A @r{<body>} containing internal definitions can always be converted +into a completely equivalent @samp{letrec} expression. For example, the +@samp{let} expression in the above example is equivalent to + + +@example + +(let ((x 5)) + (letrec ((foo (lambda (y) (bar x y))) + (bar (lambda (a b) (+ (* a b) a)))) + (foo (+ x 3)))) + +@end example + + +Just as for the equivalent @samp{letrec} expression, it must be +possible to evaluate each @r{<expression>} of every internal +definition in a @r{<body>} without assigning or referring to +the value of any @r{<variable>} being defined. + +Wherever an internal definition may occur +@t{(begin @r{<definition1>} @dots{},)} +is equivalent to the sequence of definitions +that form the body of the @code{begin}. +@vindex @w{begin} + +@node Syntax definitions, , Definitions, Program structure +@section Syntax definitions + + +Syntax definitions are valid only at the top level of a @r{<program>}. + +@cindex @w{syntax definition} +They have the following form: +@cindex @w{define-syntax} + +@t{(define-syntax @r{<keyword>} @r{<transformer spec>})} + +@r{<Keyword>} is an identifier, and +the @r{<transformer spec>} should be an instance of @code{syntax-rules}. +@vindex @w{syntax-rules} +The top-level syntactic environment is extended by binding the +@r{<keyword>} to the specified transformer. + +There is no @samp{define-syntax} analogue of internal definitions. + +@c [Rationale flushed because it may or may not be true and isn't the +@c real rationale anyway. -RK] +@c \begin{rationale} +@c As discussed below, the syntax and scope rules for syntax definitions +@c can give rise to syntactic ambiguities when syntactic keywords are +@c shadowed. +@c Further ambiguities would arise if {\cf define-syntax} +@c were permitted at the beginning of a \meta{body}, with scope +@c rules analogous to those for internal definitions. +@c \end{rationale} + +@c It is an error for a program to contain more than one top-level +@c \meta{definition} or \meta{syntax definition} of any identifier. + +@c [I flushed this because it isn't an error for a program to +@c contain more than one top-level definition of an identifier, +@c and I didn't want to introduce any gratuitous incompatibilities +@c with the existing Scheme language. -- Will] + +Although macros may expand into definitions and syntax definitions in +any context that permits them, it is an error for a definition or syntax +definition to shadow a syntactic keyword whose meaning is needed to +determine whether some form in the group of forms that contains the +shadowing definition is in fact a definition, or, for internal definitions, +is needed to determine the boundary between the group and the expressions +that follow the group. For example, the following are errors: + + +@example + +(define define 3) + +(begin (define begin list)) + +(let-syntax + ((foo (syntax-rules () + ((foo (proc args ...) body ...) + (define proc + (lambda (args ...) + body ...)))))) + (let ((x 3)) + (foo (plus x y) (+ x y)) + (define foo x) + (plus foo x))) + +@end example + + + + +@c @include{procs} + +@c Initial environment + +@c \vfill\eject +@node Standard procedures, Formal syntax and semantics, Program structure, top +@chapter Standard procedures + +@menu +* Equivalence predicates:: +* Numbers:: +* Other data types:: +* Control features:: +* Eval:: +* Input and output:: +@end menu + + + + + +@cindex @w{initial environment} + +@cindex @w{top level environment} + +@cindex @w{library procedure} + +This chapter describes Scheme's built-in procedures. The initial (or +``top level'') Scheme environment starts out with a number of variables +bound to locations containing useful values, most of which are primitive +procedures that manipulate data. For example, the variable @samp{abs} is +bound to (a location initially containing) a procedure of one argument +that computes the absolute value of a number, and the variable @samp{+} +is bound to a procedure that computes sums. Built-in procedures that +can easily be written in terms of other built-in procedures are identified as +``library procedures''. + +A program may use a top-level definition to bind any variable. It may +subsequently alter any such binding by an assignment (see @pxref{Assignments}). +These operations do not modify the behavior of Scheme's built-in +procedures. Altering any top-level binding that has not been introduced by a +definition has an unspecified effect on the behavior of the built-in procedures. + +@node Equivalence predicates, Numbers, Standard procedures, Standard procedures +@section Equivalence predicates + + + +A @dfn{predicate} is a procedure that always returns a boolean +@cindex @w{predicate} +value (@t{#t} or @t{#f}). An @dfn{equivalence predicate} is +@cindex @w{equivalence predicate} +the computational analogue of a mathematical equivalence relation (it is +symmetric, reflexive, and transitive). Of the equivalence predicates +described in this section, @samp{eq?} is the finest or most +discriminating, and @samp{equal?} is the coarsest. @samp{Eqv?} is +slightly less discriminating than @samp{eq?}. +@ignore todo +Pitman doesn't like +this paragraph. Lift the discussion from the Maclisp manual. Explain +why there's more than one predicate. +@end ignore + + + + +@deffn {procedure} eqv? obj1 obj2 + +The @samp{eqv?} procedure defines a useful equivalence relation on objects. +Briefly, it returns @t{#t} if @var{obj1} and @var{obj2} should +normally be regarded as the same object. This relation is left slightly +open to interpretation, but the following partial specification of +@samp{eqv?} holds for all implementations of Scheme. + +The @samp{eqv?} procedure returns @t{#t} if: + + + +@itemize @bullet + +@item +@var{obj1} and @var{obj2} are both @t{#t} or both @t{#f}. + +@item +@var{obj1} and @var{obj2} are both symbols and + + +@format +@t{(string=? (symbol->string obj1) + (symbol->string obj2)) + ==> #t +} +@end format + + + +@quotation +@emph{Note:} +This assumes that neither @var{obj1} nor @var{obj2} is an ``uninterned +symbol'' as alluded to in section @ref{Symbols}. This report does +not presume to specify the behavior of @samp{eqv?} on implementation-dependent +extensions. +@end quotation + + +@item +@var{obj1} and @var{obj2} are both numbers, are numerically +equal (see @samp{=}, section @pxref{Numbers}), and are either both +exact or both inexact. + +@item +@var{obj1} and @var{obj2} are both characters and are the same +character according to the @samp{char=?} procedure +(section @pxref{Characters}). + +@item +both @var{obj1} and @var{obj2} are the empty list. + +@item +@var{obj1} and @var{obj2} are pairs, vectors, or strings that denote the +same locations in the store (section @pxref{Storage model}). + +@item +@var{obj1} and @var{obj2} are procedures whose location tags are +equal (section @pxref{Procedures}). + +@end itemize + +@cindex @w{inexact} +@cindex @w{exact} + +The @samp{eqv?} procedure returns @t{#f} if: + + + +@itemize @bullet + +@item +@var{obj1} and @var{obj2} are of different types +(section @pxref{Disjointness of types}). + +@item +one of @var{obj1} and @var{obj2} is @t{#t} but the other is +@t{#f}. + +@item +@var{obj1} and @var{obj2} are symbols but + + +@format +@t{(string=? (symbol->string @var{obj1}) + (symbol->string @var{obj2})) + ==> #f +} +@end format + + +@item +one of @var{obj1} and @var{obj2} is an exact number but the other +is an inexact number. + +@item +@var{obj1} and @var{obj2} are numbers for which the @samp{=} +procedure returns @t{#f}. + +@item +@var{obj1} and @var{obj2} are characters for which the @samp{char=?} +procedure returns @t{#f}. + +@item +one of @var{obj1} and @var{obj2} is the empty list but the other +is not. + +@item +@var{obj1} and @var{obj2} are pairs, vectors, or strings that denote +distinct locations. + +@item +@var{obj1} and @var{obj2} are procedures that would behave differently +(return different value(s) or have different side effects) for some arguments. + + +@end itemize + + + +@format +@t{(eqv? 'a 'a) ==> #t +(eqv? 'a 'b) ==> #f +(eqv? 2 2) ==> #t +(eqv? '() '()) ==> #t +(eqv? 100000000 100000000) ==> #t +(eqv? (cons 1 2) (cons 1 2)) ==> #f +(eqv? (lambda () 1) + (lambda () 2)) ==> #f +(eqv? #f 'nil) ==> #f +(let ((p (lambda (x) x))) + (eqv? p p)) ==> #t +} +@end format + + +The following examples illustrate cases in which the above rules do +not fully specify the behavior of @samp{eqv?}. All that can be said +about such cases is that the value returned by @samp{eqv?} must be a +boolean. + + +@format +@t{(eqv? "" "") ==> @emph{unspecified} +(eqv? '#() '#()) ==> @emph{unspecified} +(eqv? (lambda (x) x) + (lambda (x) x)) ==> @emph{unspecified} +(eqv? (lambda (x) x) + (lambda (y) y)) ==> @emph{unspecified} +} +@end format + + +The next set of examples shows the use of @samp{eqv?} with procedures +that have local state. @samp{Gen-counter} must return a distinct +procedure every time, since each procedure has its own internal counter. +@samp{Gen-loser}, however, returns equivalent procedures each time, since +the local state does not affect the value or side effects of the +procedures. + + +@format +@t{(define gen-counter + (lambda () + (let ((n 0)) + (lambda () (set! n (+ n 1)) n)))) +(let ((g (gen-counter))) + (eqv? g g)) ==> #t +(eqv? (gen-counter) (gen-counter)) + ==> #f +(define gen-loser + (lambda () + (let ((n 0)) + (lambda () (set! n (+ n 1)) 27)))) +(let ((g (gen-loser))) + (eqv? g g)) ==> #t +(eqv? (gen-loser) (gen-loser)) + ==> @emph{unspecified} + +(letrec ((f (lambda () (if (eqv? f g) 'both 'f))) + (g (lambda () (if (eqv? f g) 'both 'g)))) + (eqv? f g)) + ==> @emph{unspecified} + +(letrec ((f (lambda () (if (eqv? f g) 'f 'both))) + (g (lambda () (if (eqv? f g) 'g 'both)))) + (eqv? f g)) + ==> #f +} +@end format + + +@c Objects of distinct types must never be regarded as the same object, +@c except that \schfalse{} and the empty list\index{empty list} are permitted to +@c be identical. + +@c \begin{scheme} +@c (eqv? '() \schfalse) \ev \unspecified% +@c \end{scheme} + +Since it is an error to modify constant objects (those returned by +literal expressions), implementations are permitted, though not +required, to share structure between constants where appropriate. Thus +the value of @samp{eqv?} on constants is sometimes +implementation-dependent. + + +@format +@t{(eqv? '(a) '(a)) ==> @emph{unspecified} +(eqv? "a" "a") ==> @emph{unspecified} +(eqv? '(b) (cdr '(a b))) ==> @emph{unspecified} +(let ((x '(a))) + (eqv? x x)) ==> #t +} +@end format + + + +@quotation +@emph{Rationale:} +The above definition of @samp{eqv?} allows implementations latitude in +their treatment of procedures and literals: implementations are free +either to detect or to fail to detect that two procedures or two literals +are equivalent to each other, and can decide whether or not to +merge representations of equivalent objects by using the same pointer or +bit pattern to represent both. +@end quotation + + +@end deffn + + + +@deffn {procedure} eq? obj1 obj2 + +@samp{Eq?} is similar to @samp{eqv?} except that in some cases it is +capable of discerning distinctions finer than those detectable by +@samp{eqv?}. + +@samp{Eq?} and @samp{eqv?} are guaranteed to have the same +behavior on symbols, booleans, the empty list, pairs, procedures, +and non-empty +strings and vectors. @samp{Eq?}'s behavior on numbers and characters is +implementation-dependent, but it will always return either true or +false, and will return true only when @samp{eqv?} would also return +true. @samp{Eq?} may also behave differently from @samp{eqv?} on empty +vectors and empty strings. + + +@format +@t{(eq? 'a 'a) ==> #t +(eq? '(a) '(a)) ==> @emph{unspecified} +(eq? (list 'a) (list 'a)) ==> #f +(eq? "a" "a") ==> @emph{unspecified} +(eq? "" "") ==> @emph{unspecified} +(eq? '() '()) ==> #t +(eq? 2 2) ==> @emph{unspecified} +(eq? #\A #\A) ==> @emph{unspecified} +(eq? car car) ==> #t +(let ((n (+ 2 3))) + (eq? n n)) ==> @emph{unspecified} +(let ((x '(a))) + (eq? x x)) ==> #t +(let ((x '#())) + (eq? x x)) ==> #t +(let ((p (lambda (x) x))) + (eq? p p)) ==> #t +} +@end format + + +@ignore todo +Needs to be explained better above. How can this be made to be +not confusing? A table maybe? +@end ignore + + + +@quotation +@emph{Rationale:} It will usually be possible to implement @samp{eq?} much +more efficiently than @samp{eqv?}, for example, as a simple pointer +comparison instead of as some more complicated operation. One reason is +that it may not be possible to compute @samp{eqv?} of two numbers in +constant time, whereas @samp{eq?} implemented as pointer comparison will +always finish in constant time. @samp{Eq?} may be used like @samp{eqv?} +in applications using procedures to implement objects with state since +it obeys the same constraints as @samp{eqv?}. +@end quotation + + +@end deffn + + + +@deffn {library procedure} equal? obj1 obj2 + +@samp{Equal?} recursively compares the contents of pairs, vectors, and +strings, applying @samp{eqv?} on other objects such as numbers and symbols. +A rule of thumb is that objects are generally @samp{equal?} if they print +the same. @samp{Equal?} may fail to terminate if its arguments are +circular data structures. + + +@format +@t{(equal? 'a 'a) ==> #t +(equal? '(a) '(a)) ==> #t +(equal? '(a (b) c) + '(a (b) c)) ==> #t +(equal? "abc" "abc") ==> #t +(equal? 2 2) ==> #t +(equal? (make-vector 5 'a) + (make-vector 5 'a)) ==> #t +(equal? (lambda (x) x) + (lambda (y) y)) ==> @emph{unspecified} +} +@end format + + +@end deffn + + +@node Numbers, Other data types, Equivalence predicates, Standard procedures +@section Numbers + +@menu +* Numerical types:: +* Exactness:: +* Implementation restrictions:: +* Syntax of numerical constants:: +* Numerical operations:: +* Numerical input and output:: +@end menu + + + +@cindex @w{number} + +@c %R4%% The excessive use of the code font in this section was +@c confusing, somewhat obnoxious, and inconsistent with the rest +@c of the report and with parts of the section itself. I added +@c a \tupe no-op, and changed most old uses of \type to \tupe, +@c to make it easier to change the fonts back if people object +@c to the change. + +@c \newcommand{\type}[1]{{\it#1}} +@c \newcommand{\tupe}[1]{{#1}} + +Numerical computation has traditionally been neglected by the Lisp +community. Until Common Lisp there was no carefully thought out +strategy for organizing numerical computation, and with the exception of +the MacLisp system [Pitman83] little effort was made to +execute numerical code efficiently. This report recognizes the excellent work +of the Common Lisp committee and accepts many of their recommendations. +In some ways this report simplifies and generalizes their proposals in a manner +consistent with the purposes of Scheme. + +It is important to distinguish between the mathematical numbers, the +Scheme numbers that attempt to model them, the machine representations +used to implement the Scheme numbers, and notations used to write numbers. +This report uses the types @i{number}, @i{complex}, @i{real}, +@i{rational}, and @i{integer} to refer to both mathematical numbers +and Scheme numbers. Machine representations such as fixed point and +floating point are referred to by names such as @i{fixnum} and +@i{flonum}. + +@c %R4%% I did some reorganizing here to move the discussion of mathematical +@c numbers before the discussion of the Scheme numbers, hoping that this +@c would help to motivate the discussion of representation independence. + +@node Numerical types, Exactness, Numbers, Numbers +@subsection Numerical types + + + +@cindex @w{numerical types} + +@c %R4%% A Scheme system provides data of type \type{number}, which is the most +@c general numerical type supported by that system. +@c \type{Number} is +@c likely to be a complicated union type implemented in terms of +@c \type{fixnum}s, \type{bignum}s, \type{flonum}s, and so forth, but this +@c should not be apparent to a naive user. What the user should see is +@c that the usual operations on numbers produce the mathematically +@c expected results, within the limits of the implementation. + +@c %R4%% I rewrote the following paragraph to make the various levels of +@c the tower into subsets of each other, instead of relating them by +@c injections. I think the injections tended to put people in the frame +@c of mind of thinking about coercions between non-overlapping numeric +@c types in mainstream programming languages. + +Mathematically, numbers may be arranged into a tower of subtypes +@c %R4%% with injections relating adjacent levels of the tower: +in which each level is a subset of the level above it: + +@format + @r{number} + @r{complex} + @r{real} + @r{rational} + @r{integer} +@end format + + +For example, 3 is an integer. Therefore 3 is also a rational, +a real, and a complex. The same is true of the Scheme numbers +that model 3. For Scheme numbers, these types are defined by the +predicates @code{number?}, @code{complex?}, @code{real?}, @code{rational?}, +@vindex @w{rational?} +@vindex @w{real?} +@vindex @w{complex?} +@vindex @w{number?} +and @code{integer?}. +@vindex @w{integer?} + +There is no simple relationship between a number's type and its +representation inside a computer. Although most implementations of +Scheme will offer at least two different representations of 3, these +different representations denote the same integer. + +@c %R4%% I moved "Implementations of Scheme are not required to implement +@c the whole tower..." to the subsection on implementation restrictions. + +Scheme's numerical operations treat numbers as abstract data, as +independent of their representation as possible. Although an implementation +of Scheme may use fixnum, flonum, and perhaps other representations for +numbers, this should not be apparent to a casual programmer writing +simple programs. + +It is necessary, however, to distinguish between numbers that are +represented exactly and those that may not be. For example, indexes +into data structures must be known exactly, as must some polynomial +coefficients in a symbolic algebra system. On the other hand, the +results of measurements are inherently inexact, and irrational numbers +may be approximated by rational and therefore inexact approximations. +In order to catch uses of inexact numbers where exact numbers are +required, Scheme explicitly distinguishes exact from inexact numbers. +This distinction is orthogonal to the dimension of type. + +@node Exactness, Implementation restrictions, Numerical types, Numbers +@subsection Exactness + + +@c %R4%% I tried to direct the following paragraph away from philosophizing +@c about the exactness of mathematical numbers, and toward philosophizing +@c about the exactness of Scheme numbers. + + +@cindex @w{exactness} +Scheme numbers are either @i{exact} or @i{inexact}. A number is +@r{exact} if it was written as an exact constant or was derived from +@r{exact} numbers using only @r{exact} operations. A number is +@r{inexact} if it was written as an inexact constant, +@c %R4%% models a quantity (e.g., a measurement) known only approximately, +if it was +derived using @r{inexact} ingredients, or if it was derived using +@r{inexact} operations. Thus @r{inexact}ness is a contagious +property of a number. +@c %R4%% The rest of this paragraph (from R3RS) has been dropped. + +If two implementations produce @r{exact} results for a +computation that did not involve @r{inexact} intermediate results, +the two ultimate results will be mathematically equivalent. This is +generally not true of computations involving @r{inexact} numbers +since approximate methods such as floating point arithmetic may be used, +but it is the duty of each implementation to make the result as close as +practical to the mathematically ideal result. + +Rational operations such as @samp{+} should always produce +@r{exact} results when given @r{exact} arguments. +@c %R4%%If an implementation is +@c unable to represent an \tupe{exact} result (for example, if it does not +@c support infinite precision integers and rationals) +If the operation is unable to produce an @r{exact} result, +then it may either report the violation of an implementation restriction +or it may silently coerce its +result to an @r{inexact} value. +@c %R4%%Such a coercion may cause an error later. +See section @ref{Implementation restrictions}. + +With the exception of @code{inexact->exact}, the operations described in +@vindex @w{inexact->exact} +this section must generally return inexact results when given any inexact +arguments. An operation may, however, return an @r{exact} result if it can +prove that the value of the result is unaffected by the inexactness of its +arguments. For example, multiplication of any number by an @r{exact} zero +may produce an @r{exact} zero result, even if the other argument is +@r{inexact}. + +@node Implementation restrictions, Syntax of numerical constants, Exactness, Numbers +@subsection Implementation restrictions + + + +@cindex @w{implementation restriction} + +Implementations of Scheme are not required to implement the whole +tower of subtypes given in section @ref{Numerical types}, +but they must implement a coherent subset consistent with both the +purposes of the implementation and the spirit of the Scheme language. +For example, an implementation in which all numbers are @r{real} +may still be quite useful. + +Implementations may also support only a limited range of numbers of +any type, subject to the requirements of this section. The supported +range for @r{exact} numbers of any type may be different from the +supported range for @r{inexact} numbers of that type. For example, +an implementation that uses flonums to represent all its +@r{inexact} @r{real} numbers may +support a practically unbounded range of @r{exact} @r{integer}s +and @r{rational}s +while limiting the range of @r{inexact} @r{real}s (and therefore +the range of @r{inexact} @r{integer}s and @r{rational}s) +to the dynamic range of the flonum format. +Furthermore +the gaps between the representable @r{inexact} @r{integer}s and +@r{rational}s are +likely to be very large in such an implementation as the limits of this +range are approached. + +An implementation of Scheme must support exact integers +throughout the range of numbers that may be used for indexes of +lists, vectors, and strings or that may result from computing the length of a +list, vector, or string. The @code{length}, @code{vector-length}, +@vindex @w{vector-length} +@vindex @w{length} +and @code{string-length} procedures must return an exact +@vindex @w{string-length} +integer, and it is an error to use anything but an exact integer as an +index. Furthermore any integer constant within the index range, if +expressed by an exact integer syntax, will indeed be read as an exact +integer, regardless of any implementation restrictions that may apply +outside this range. Finally, the procedures listed below will always +return an exact integer result provided all their arguments are exact integers +and the mathematically expected result is representable as an exact integer +within the implementation: + + +@example + ++ - * +quotient remainder modulo +max min abs +numerator denominator gcd +lcm floor ceiling +truncate round rationalize +expt + +@end example + + +Implementations are encouraged, but not required, to support +@r{exact} @r{integer}s and @r{exact} @r{rational}s of +practically unlimited size and precision, and to implement the +above procedures and the @samp{/} procedure in +such a way that they always return @r{exact} results when given @r{exact} +arguments. If one of these procedures is unable to deliver an @r{exact} +result when given @r{exact} arguments, then it may either report a +violation of an +implementation restriction or it may silently coerce its result to an +@r{inexact} number. Such a coercion may cause an error later. + +@c %R4%% I moved this stuff here. +@c It seems to me that the only thing that this requires is that +@c implementations that support inexact numbers have to have both +@c exact and inexact representations for the integers 0 through 15. +@c If that's what it's saying, I'd rather say it that way. +@c On the other hand, letting the limit be as small as 15 sounds a +@c tad silly, though I think I understand how that number was arrived at. +@c (Or is 35 the number?) + +@c Implementations are encouraged, but not required, to support \tupe{inexact} +@c numbers. For any implementation that supports \tupe{inexact} numbers, +@c there is a subset of the integers for which there are both \tupe{exact} and +@c \tupe{inexact} representations. This subset must include all non-negative +@c integers up to some limit specified by the implementation. This limit +@c must be 16 or greater. The +@c \ide{exact\coerce{}inexact} and \ide{inexact\coerce{}exact} +@c procedures implement the natural one-to-one correspondence between +@c the \tupe{inexact} and \tupe{exact} integers within this range. + +An implementation may use floating point and other approximate +representation strategies for @r{inexact} numbers. +@c %R4%% The following sentence seemed a bit condescending as well as +@c awkward. It didn't seem to be very enforceable, so I flushed it. + +@c This is not to +@c say that implementors need not use the best known algorithms for +@c \tupe{inexact} computations---only that approximate methods of high +@c quality are allowed. + +This report recommends, but does not require, that the IEEE 32-bit +and 64-bit floating point standards be followed by implementations that use +flonum representations, and that implementations using +other representations should match or exceed the precision achievable +using these floating point standards [IEEE]. + +In particular, implementations that use flonum representations +must follow these rules: A @r{flonum} result +must be represented with at least as much precision as is used to express any of +the inexact arguments to that operation. It is desirable (but not required) for +potentially inexact operations such as @samp{sqrt}, when applied to @r{exact} +arguments, to produce @r{exact} answers whenever possible (for example the +square root of an @r{exact} 4 ought to be an @r{exact} 2). +If, however, an +@r{exact} number is operated upon so as to produce an @r{inexact} result +(as by @samp{sqrt}), and if the result is represented as a @r{flonum}, then +the most precise @r{flonum} format available must be used; but if the result +is represented in some other way then the representation must have at least as +much precision as the most precise @r{flonum} format available. + +Although Scheme allows a variety of written +@c %R4%% representations of +notations for +numbers, any particular implementation may support only some of them. +@c %R4%% +For example, an implementation in which all numbers are @r{real} +need not support the rectangular and polar notations for complex +numbers. If an implementation encounters an @r{exact} numerical constant that +it cannot represent as an @r{exact} number, then it may either report a +violation of an implementation restriction or it may silently represent the +constant by an @r{inexact} number. + + +@node Syntax of numerical constants, Numerical operations, Implementation restrictions, Numbers +@subsection Syntax of numerical constants + + + +@c @@@@LOSE@@@@ + +@c %R4%% I removed the following paragraph in an attempt to tighten up +@c this subsection. Except for its first sentence, which I moved to +@c the subsection on implementation restrictions, I think its content +@c is implied by the rest of the section. + +@c Although Scheme allows a variety of written representations of numbers, +@c any particular implementation may support only some of them. +@c These syntaxes are intended to be purely notational; any kind of number +@c may be written in any form that the user deems convenient. Of course, +@c writing 1/7 as a limited-precision decimal fraction will not express the +@c number exactly, but this approximate form of expression may be just what +@c the user wants to see. + +The syntax of the written representations for numbers is described formally in +section @ref{Lexical structure}. Note that case is not significant in numerical +constants. + +@c %R4%% See section~\ref{numberformats} for many examples. + +A number may be written in binary, octal, decimal, or +hexadecimal by the use of a radix prefix. The radix prefixes are @samp{#b} (binary), @samp{#o} (octal), @samp{#d} (decimal), and @samp{#x} (hexadecimal). With +@vindex #x +@vindex #d +@vindex #o +@vindex #b +no radix prefix, a number is assumed to be expressed in decimal. + +A +@c %R4%% +@c simple +numerical constant may be specified to be either @r{exact} or +@r{inexact} by a prefix. The prefixes are @samp{#e} +@vindex #e +for @r{exact}, and @samp{#i} for @r{inexact}. An exactness +@vindex #i +prefix may appear before or after any radix prefix that is used. If +the written representation of a number has no exactness prefix, the +constant may be either @r{inexact} or @r{exact}. It is +@r{inexact} if it contains a decimal point, an +exponent, or a ``#'' character in the place of a digit, +otherwise it is @r{exact}. +@c %R4%% With our new syntax, the following sentence is redundant: + +@c The written representation of a +@c compound number, such as a ratio or a complex, is exact if and only if +@c all of its constituents are exact. + +In systems with @r{inexact} numbers +of varying precisions it may be useful to specify +the precision of a constant. For this purpose, numerical constants +may be written with an exponent marker that indicates the +desired precision of the @r{inexact} +representation. The letters @samp{s}, @samp{f}, +@samp{d}, and @samp{l} specify the use of @var{short}, @var{single}, +@var{double}, and @var{long} precision, respectively. (When fewer +than four internal +@c %R4%%\tupe{flonum} +@r{inexact} +representations exist, the four size +specifications are mapped onto those available. For example, an +implementation with two internal representations may map short and +single together and long and double together.) In addition, the +exponent marker @samp{e} specifies the default precision for the +implementation. The default precision has at least as much precision +as @var{double}, but +implementations may wish to allow this default to be set by the user. + + +@example + +3.14159265358979F0 + @r{Round to single ---} 3.141593 +0.6L0 + @r{Extend to long ---} .600000000000000 + +@end example + + + +@node Numerical operations, Numerical input and output, Syntax of numerical constants, Numbers +@subsection Numerical operations + + +The reader is referred to section @ref{Entry format} for a summary +of the naming conventions used to specify restrictions on the types of +arguments to numerical routines. +@c %R4%% The following sentence has already been said twice, and the +@c term "exactness-preserving" is no longer defined by the Report. + +@c Remember that +@c an exactness-preserving operation may coerce its result to inexact if the +@c implementation is unable to represent it exactly. +The examples used in this section assume that any numerical constant written +using an @r{exact} notation is indeed represented as an @r{exact} +number. Some examples also assume that certain numerical constants written +using an @r{inexact} notation can be represented without loss of +accuracy; the @r{inexact} constants were chosen so that this is +likely to be true in implementations that use flonums to represent +inexact numbers. + +@ignore todo +Scheme provides the usual set of operations for manipulating +numbers, etc. +@end ignore + + + +@deffn {procedure} number? obj +@deffnx {procedure} complex? obj +@deffnx {procedure} real? obj +@deffnx {procedure} rational? obj +@deffnx {procedure} integer? obj + +These numerical type predicates can be applied to any kind of +argument, including non-numbers. They return @t{#t} if the object is +of the named type, and otherwise they return @t{#f}. +In general, if a type predicate is true of a number then all higher +type predicates are also true of that number. Consequently, if a type +predicate is false of a number, then all lower type predicates are +also false of that number. +@c %R4%% The new section on implementation restrictions subsumes: +@c Not every system +@c supports all of these types; for example, it is entirely possible to have a +@c Scheme system that has only \tupe{integer}s. Nonetheless every implementation +@c of Scheme must have all of these predicates. + +If @var{z} is an inexact complex number, then @samp{(real? @var{z})} is true if +and only if @samp{(zero? (imag-part @var{z}))} is true. If @var{x} is an inexact +real number, then @samp{(integer? @var{x})} is true if and only if +@samp{(= @var{x} (round @var{x}))}. + + +@format +@t{(complex? 3+4i) ==> #t +(complex? 3) ==> #t +(real? 3) ==> #t +(real? -2.5+0.0i) ==> #t +(real? #e1e10) ==> #t +(rational? 6/10) ==> #t +(rational? 6/3) ==> #t +(integer? 3+0i) ==> #t +(integer? 3.0) ==> #t +(integer? 8/4) ==> #t +} +@end format + + + +@quotation +@emph{Note:} +The behavior of these type predicates on @r{inexact} numbers +is unreliable, since any inaccuracy may affect the result. +@end quotation + + + +@quotation +@emph{Note:} +In many implementations the @code{rational?} procedure will be the same +@vindex @w{rational?} +as @code{real?}, and the @code{complex?} procedure will be the same as +@vindex @w{complex?} +@vindex @w{real?} +@code{number?}, but unusual implementations may be able to represent +@vindex @w{number?} +some irrational numbers exactly or may extend the number system to +support some kind of non-complex numbers. +@end quotation + + +@end deffn + + +@deffn {procedure} exact? @var{z} +@deffnx {procedure} inexact? @var{z} + +These numerical predicates provide tests for the exactness of a +quantity. For any Scheme number, precisely one of these predicates +is true. + +@end deffn + + + +@deffn {procedure} = z1 z2 z3 @dots{}, +@deffnx {procedure} < x1 x2 x3 @dots{}, +@deffnx {procedure} > x1 x2 x3 @dots{}, +@deffnx {procedure} <= x1 x2 x3 @dots{}, +@deffnx {procedure} >= x1 x2 x3 @dots{}, + +@c - Some implementations allow these procedures to take many arguments, to +@c - facilitate range checks. +These procedures return @t{#t} if their arguments are (respectively): +equal, monotonically increasing, monotonically decreasing, +monotonically nondecreasing, or monotonically nonincreasing. + +These predicates are required to be transitive. + + +@quotation +@emph{Note:} +The traditional implementations of these predicates in Lisp-like +languages are not transitive. +@end quotation + + + +@quotation +@emph{Note:} +While it is not an error to compare @r{inexact} numbers using these +predicates, the results may be unreliable because a small inaccuracy +may affect the result; this is especially true of @code{=} and @code{zero?}. +@vindex @w{zero?} +@vindex @w{=} +When in doubt, consult a numerical analyst. +@end quotation + + +@end deffn + + +@deffn {library procedure} zero? @var{z} +@deffnx {library procedure} positive? @var{x} +@deffnx {library procedure} negative? @var{x} +@deffnx {library procedure} odd? @var{n} +@deffnx {library procedure} even? @var{n} + +These numerical predicates test a number for a particular property, +returning @t{#t} or @t{#f}. See note above. + +@end deffn + + +@deffn {library procedure} max x1 x2 @dots{}, +@deffnx {library procedure} min x1 x2 @dots{}, + +These procedures return the maximum or minimum of their arguments. + + +@format +@t{(max 3 4) ==> 4 ; exact +(max 3.9 4) ==> 4.0 ; inexact +} +@end format + + + +@quotation +@emph{Note:} +If any argument is inexact, then the result will also be inexact (unless +the procedure can prove that the inaccuracy is not large enough to affect the +result, which is possible only in unusual implementations). If @samp{min} or +@samp{max} is used to compare numbers of mixed exactness, and the numerical +value of the result cannot be represented as an inexact number without loss of +accuracy, then the procedure may report a violation of an implementation +restriction. +@end quotation + + +@end deffn + + + +@deffn {procedure} + z1 @dots{}, +@deffnx {procedure} * z1 @dots{}, + +These procedures return the sum or product of their arguments. +@c - These procedures are exactness preserving. + + +@format +@t{(+ 3 4) ==> 7 +(+ 3) ==> 3 +(+) ==> 0 +(* 4) ==> 4 +(*) ==> 1 +} +@end format + + +@end deffn + + + +@deffn {procedure} - z1 z2 +@deffnx {procedure} - @var{z} +@deffnx {optional procedure} - z1 z2 @dots{}, +@deffnx {procedure} / z1 z2 +@deffnx {procedure} / @var{z} +@deffnx {optional procedure} / z1 z2 @dots{}, + +With two or more arguments, these procedures return the difference or +quotient of their arguments, associating to the left. With one argument, +however, they return the additive or multiplicative inverse of their argument. +@c - These procedures are exactness preserving, except that division may +@c - coerce its result to inexact in implementations that do not support +@c - \tupe{ratnum}s. + + +@format +@t{(- 3 4) ==> -1 +(- 3 4 5) ==> -6 +(- 3) ==> -3 +(/ 3 4 5) ==> 3/20 +(/ 3) ==> 1/3 +} +@end format + + +@end deffn + + + +@deffn {library procedure} abs x + +@samp{Abs} returns the absolute value of its argument. +@c - {\cf Abs} is exactness preserving when its argument is real. + +@format +@t{(abs -7) ==> 7 +} +@end format + +@end deffn + + + +@deffn {procedure} quotient n1 n2 +@deffnx {procedure} remainder n1 n2 +@deffnx {procedure} modulo n1 n2 + +These procedures implement number-theoretic (integer) +division. @var{n2} should be non-zero. All three procedures +return integers. If @var{n1}/@var{n2} is an integer: + +@format +@t{ (quotient @var{n1} @var{n2}) ==> @var{n1}/@var{n2} + (remainder @var{n1} @var{n2}) ==> 0 + (modulo @var{n1} @var{n2}) ==> 0 +} +@end format + +If @var{n1}/@var{n2} is not an integer: + +@format +@t{ (quotient @var{n1} @var{n2}) ==> @var{n_q} + (remainder @var{n1} @var{n2}) ==> @var{n_r} + (modulo @var{n1} @var{n2}) ==> @var{n_m} +} +@end format + +where @var{n_q} is @var{n1}/@var{n2} rounded towards zero, +0 < |@var{n_r}| < |@var{n2}|, 0 < |@var{n_m}| < |@var{n2}|, +@var{n_r} and @var{n_m} differ from @var{n1} by a multiple of @var{n2}, +@var{n_r} has the same sign as @var{n1}, and +@var{n_m} has the same sign as @var{n2}. + +From this we can conclude that for integers @var{n1} and @var{n2} with +@var{n2} not equal to 0, + +@format +@t{ (= @var{n1} (+ (* @var{n2} (quotient @var{n1} @var{n2})) + (remainder @var{n1} @var{n2}))) + ==> #t +} +@end format + +provided all numbers involved in that computation are exact. + + +@format +@t{(modulo 13 4) ==> 1 +(remainder 13 4) ==> 1 + +(modulo -13 4) ==> 3 +(remainder -13 4) ==> -1 + +(modulo 13 -4) ==> -3 +(remainder 13 -4) ==> 1 + +(modulo -13 -4) ==> -1 +(remainder -13 -4) ==> -1 + +(remainder -13 -4.0) ==> -1.0 ; inexact +} +@end format + +@end deffn + + +@deffn {library procedure} gcd n1 @dots{}, +@deffnx {library procedure} lcm n1 @dots{}, + +These procedures return the greatest common divisor or least common +multiple of their arguments. The result is always non-negative. +@c - These procedures are exactness preserving. + +@c %R4%% I added the inexact example. + +@format +@t{(gcd 32 -36) ==> 4 +(gcd) ==> 0 +(lcm 32 -36) ==> 288 +(lcm 32.0 -36) ==> 288.0 ; inexact +(lcm) ==> 1 +} +@end format + + +@end deffn + + + +@deffn {procedure} numerator @var{q} +@deffnx {procedure} denominator @var{q} + +These procedures return the numerator or denominator of their +argument; the result is computed as if the argument was represented as +a fraction in lowest terms. The denominator is always positive. The +denominator of 0 is defined to be 1. +@c - The remarks about denominators are new. +@c - Clearly, they are exactness-preserving procedures. + +@ignore todo +More description and examples needed. +@end ignore + + +@format +@t{(numerator (/ 6 4)) ==> 3 +(denominator (/ 6 4)) ==> 2 +(denominator + (exact->inexact (/ 6 4))) ==> 2.0 +} +@end format + + +@end deffn + + + +@deffn {procedure} floor x +@deffnx {procedure} ceiling x +@deffnx {procedure} truncate x +@deffnx {procedure} round x + + +These procedures return integers. +@samp{Floor} returns the largest integer not larger than @var{x}. +@samp{Ceiling} returns the smallest integer not smaller than @var{x}. +@samp{Truncate} returns the integer closest to @var{x} whose absolute +value is not larger than the absolute value of @var{x}. @samp{Round} returns the +closest integer to @var{x}, rounding to even when @var{x} is halfway between two +integers. + + +@quotation +@emph{Rationale:} +@samp{Round} rounds to even for consistency with the default rounding +mode specified by the IEEE floating point standard. +@end quotation + + + +@quotation +@emph{Note:} +If the argument to one of these procedures is inexact, then the result +will also be inexact. If an exact value is needed, the +result should be passed to the @samp{inexact->exact} procedure. +@end quotation + + + +@format +@t{(floor -4.3) ==> -5.0 +(ceiling -4.3) ==> -4.0 +(truncate -4.3) ==> -4.0 +(round -4.3) ==> -4.0 + +(floor 3.5) ==> 3.0 +(ceiling 3.5) ==> 4.0 +(truncate 3.5) ==> 3.0 +(round 3.5) ==> 4.0 ; inexact + +(round 7/2) ==> 4 ; exact +(round 7) ==> 7 +} +@end format + + +@end deffn + + +@deffn {library procedure} rationalize x y +@c - \proto{rationalize}{ x}{procedure} + + +@samp{Rationalize} returns the @emph{simplest} rational number +differing from @var{x} by no more than @var{y}. A rational number r_1 is +@emph{simpler} than another rational number +@cindex @w{simplest rational} +r_2 if r_1 = p_1/q_1 and r_2 = p_2/q_2 (in lowest terms) and |p_1|<= |p_2| and |q_1| <= |q_2|. Thus 3/5 is simpler than 4/7. +Although not all rationals are comparable in this ordering (consider 2/7 +and 3/5) any interval contains a rational number that is simpler than +every other rational number in that interval (the simpler 2/5 lies +between 2/7 and 3/5). Note that 0 = 0/1 is the simplest rational of +all. + + +@format +@t{(rationalize + (inexact->exact .3) 1/10) ==> 1/3 ; exact +(rationalize .3 1/10) ==> #i1/3 ; inexact +} +@end format + + +@end deffn + + +@deffn {procedure} exp @var{z} +@deffnx {procedure} log @var{z} +@deffnx {procedure} sin @var{z} +@deffnx {procedure} cos @var{z} +@deffnx {procedure} tan @var{z} +@deffnx {procedure} asin @var{z} +@deffnx {procedure} acos @var{z} +@deffnx {procedure} atan @var{z} +@deffnx {procedure} atan @var{y} @var{x} + +These procedures are part of every implementation that supports +@c %R4%% +general +real numbers; they compute the usual transcendental functions. @samp{Log} +computes the natural logarithm of @var{z} (not the base ten logarithm). +@samp{Asin}, @samp{acos}, and @samp{atan} compute arcsine (sin^-1), +arccosine (cos^-1), and arctangent (tan^-1), respectively. +The two-argument variant of @samp{atan} computes @t{(angle +(make-rectangular @var{x} @var{y}))} (see below), even in implementations +that don't support general complex numbers. + +In general, the mathematical functions log, arcsine, arccosine, and +arctangent are multiply defined. +The value of log z is defined to be the one whose imaginary +part lies in the range from -pi (exclusive) to pi (inclusive). +log 0 is undefined. +With log defined this way, the values of sin^-1 z, cos^-1 z, +and tan^-1 z are according to the following formulae: + + +@center sin^-1 z = -i log (i z + sqrt1 - z^2) + + + +@center cos^-1 z = pi / 2 - sin^-1 z + + + +@center tan^-1 z = (log (1 + i z) - log (1 - i z)) / (2 i) + + +The above specification follows [CLtL], which in turn +cites [Penfield81]; refer to these sources for more detailed +discussion of branch cuts, boundary conditions, and implementation of +these functions. When it is possible these procedures produce a real +result from a real argument. + +@c %R4%% + +@ignore todo +The cited references are likely to change their branch cuts +soon to allow for the possibility of distinct positive and negative +zeroes, as in IEEE floating point. We may not want to follow those +changes, since we may want a complex number with zero imaginary part +(whether positive or negative zero) to be treated as a real. I don't +think there are any better standards for complex arithmetic than the +ones cited, so we're really on our own here. +@end ignore + + +@end deffn + + + +@deffn {procedure} sqrt @var{z} + +Returns the principal square root of @var{z}. The result will have +either positive real part, or zero real part and non-negative imaginary +part. +@end deffn + + + +@deffn {procedure} expt z1 z2 + +Returns @var{z1} raised to the power @var{z2}. For z_1 ~= 0 + + +@center z_1^z_2 = e^z_2 log z_1 + +0^z is 1 if z = 0 and 0 otherwise. +@end deffn + +@c - \begin{entry}{%- +@c - \proto{approximate}{ z x}{procedure}} +@c - +@c - Returns an approximation to \vr{z} in a representation whose precision is +@c - the same as that +@c - of the representation of \vr{x}, which must be an inexact number. The +@c - result is always inexact. +@c - +@c - \begin{scheme} +@c - (approximate 3.1415926535 1F10) +@c - \ev 3.14159F0 +@c - (approximate 3.1415926535 \#I65535) +@c - \ev \#I3 +@c - (approximate 3.14F0 1L8) +@c - \ev 3.14L0 +@c - (approximate 3.1415926535F0 1L8) +@c - \ev 3.14159L0 +@c - \end{scheme} +@c - \end{entry} + + + + +@deffn {procedure} make-rectangular x1 x2 +@deffnx {procedure} make-polar x3 x4 +@deffnx {procedure} real-part @var{z} +@deffnx {procedure} imag-part @var{z} +@deffnx {procedure} magnitude @var{z} +@deffnx {procedure} angle @var{z} + +These procedures are part of every implementation that supports +@c %R4%% +general +complex numbers. Suppose @var{x1}, @var{x2}, @var{x3}, and @var{x4} are +real numbers and @var{z} is a complex number such that + + +@center @var{z} = @var{x1} + @var{x2}@w{i} = @var{x3} . e^@w{i} @var{x4} + +Then + +@format +@t{(make-rectangular @var{x1} @var{x2}) ==> @var{z} +(make-polar @var{x3} @var{x4}) ==> @var{z} +(real-part @var{z}) ==> @var{x1} +(imag-part @var{z}) ==> @var{x2} +(magnitude @var{z}) ==> |@var{x3}| +(angle @var{z}) ==> x_angle +} +@end format + +where -pi < x_angle <= pi with x_angle = @var{x4} + 2pi n +for some integer n. + + +@quotation +@emph{Rationale:} +@samp{Magnitude} is the same as @code{abs} for a real argument, +@vindex @w{abs} +but @samp{abs} must be present in all implementations, whereas +@samp{magnitude} need only be present in implementations that support +general complex numbers. +@end quotation + + +@end deffn + + + +@deffn {procedure} exact->inexact @var{z} +@deffnx {procedure} inexact->exact @var{z} + +@samp{Exact->inexact} returns an @r{inexact} representation of @var{z}. +The value returned is the +@r{inexact} number that is numerically closest to the argument. +@c %R4%%For +@c \tupe{exact} arguments which have no reasonably close \tupe{inexact} equivalent, +@c it is permissible to signal an error. +If an @r{exact} argument has no reasonably close @r{inexact} equivalent, +then a violation of an implementation restriction may be reported. + +@samp{Inexact->exact} returns an @r{exact} representation of +@var{z}. The value returned is the @r{exact} number that is numerically +closest to the argument. +@c %R4%% For \tupe{inexact} arguments which have no +@c reasonably close \tupe{exact} equivalent, it is permissible to signal +@c an error. +If an @r{inexact} argument has no reasonably close @r{exact} equivalent, +then a violation of an implementation restriction may be reported. + +@c %R%% I moved this to the section on implementation restrictions. +@c For any implementation that supports \tupe{inexact} quantities, +@c there is a subset of the integers for which there are both \tupe{exact} and +@c \tupe{inexact} representations. This subset must include the non-negative +@c integers up to a limit specified by the implementation. The limit +@c must be big enough to represent all digits in reasonable radices, and +@c may correspond to some natural word size for the implementation. For +@c such integers, these procedures implement the natural one-to-one +@c correspondence between the representations. + +These procedures implement the natural one-to-one correspondence between +@r{exact} and @r{inexact} integers throughout an +implementation-dependent range. See section @ref{Implementation restrictions}. + +@end deffn + +@sp 3 + +@node Numerical input and output, , Numerical operations, Numbers +@subsection Numerical input and output + + + +@deffn {procedure} number->string z +@deffnx {procedure} number->string z radix + +@var{Radix} must be an exact integer, either 2, 8, 10, or 16. If omitted, +@var{radix} defaults to 10. +The procedure @samp{number->string} takes a +number and a radix and returns as a string an external representation of +the given number in the given radix such that + +@format +@t{(let ((number @var{number}) + (radix @var{radix})) + (eqv? number + (string->number (number->string number + radix) + radix))) +} +@end format + +is true. It is an error if no possible result makes this expression true. + +If @var{z} is inexact, the radix is 10, and the above expression +can be satisfied by a result that contains a decimal point, +then the result contains a decimal point and is expressed using the +minimum number of digits (exclusive of exponent and trailing +zeroes) needed to make the above expression +true [howtoprint], [howtoread]; +otherwise the format of the result is unspecified. + +The result returned by @samp{number->string} +never contains an explicit radix prefix. + + +@quotation +@emph{Note:} +The error case can occur only when @var{z} is not a complex number +or is a complex number with a non-rational real or imaginary part. +@end quotation + + + +@quotation +@emph{Rationale:} +If @var{z} is an inexact number represented using flonums, and +the radix is 10, then the above expression is normally satisfied by +a result containing a decimal point. The unspecified case +allows for infinities, NaNs, and non-flonum representations. +@end quotation + + +@end deffn + + + +@deffn {procedure} string->number string +@deffnx {procedure} string->number string radix + +@c %R4%% I didn't include the (string->number string radix exactness) +@c case, since I haven't heard any resolution of the coding to be used +@c for the third argument. + +Returns 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. @t{"#o177"}). If @var{radix} +is not supplied, then the default radix is 10. If @var{string} is not +a syntactically valid notation for a number, then @samp{string->number} +returns @t{#f}. + + +@format +@t{(string->number "100") ==> 100 +(string->number "100" 16) ==> 256 +(string->number "1e2") ==> 100.0 +(string->number "15##") ==> 1500.0 +} +@end format + + + +@quotation +@emph{Note:} +The domain of @samp{string->number} may be restricted by implementations +in the following ways. @samp{String->number} is permitted to return +@t{#f} whenever @var{string} contains an explicit radix prefix. +If all numbers supported by an implementation are real, then +@samp{string->number} is permitted to return @t{#f} whenever +@var{string} uses the polar or rectangular notations for complex +numbers. If all numbers are integers, then +@samp{string->number} may return @t{#f} whenever +the fractional notation is used. If all numbers are exact, then +@samp{string->number} may return @t{#f} whenever +an exponent marker or explicit exactness prefix is used, or if +a @t{#} appears in place of a digit. If all inexact +numbers are integers, then +@samp{string->number} may return @t{#f} whenever +a decimal point is used. +@end quotation + + +@end deffn + +@node Other data types, Control features, Numbers, Standard procedures +@section Other data types + +@menu +* Booleans:: +* Pairs and lists:: +* Symbols:: +* Characters:: +* Strings:: +* Vectors:: +@end menu + + +This section describes operations on some of Scheme's non-numeric data types: +booleans, pairs, lists, symbols, characters, strings and vectors. + +@node Booleans, Pairs and lists, Other data types, Other data types +@subsection Booleans + + + +The standard boolean objects for true and false are written as +@t{#t} and @t{#f}. What really +@vindex #f +@vindex #t +matters, though, are the objects that the Scheme conditional expressions +(@samp{if}, @samp{cond}, @samp{and}, @samp{or}, @samp{do}) treat as +true or false. The phrase ``a true value'' +@cindex @w{false} +@cindex @w{true} +(or sometimes just ``true'') means any object treated as true by the +conditional expressions, and the phrase ``a false value'' (or +@cindex @w{false} +``false'') means any object treated as false by the conditional expressions. + +Of all the standard Scheme values, only @t{#f} +@c is guaranteed to count +counts as false in conditional expressions. +@c It is not +@c specified whether the empty list\index{empty list} counts as false +@c or as true in conditional expressions. +Except for @t{#f}, +@c and possibly the empty list, +all standard Scheme values, including @t{#t}, +pairs, the empty list, symbols, numbers, strings, vectors, and procedures, +count as true. + +@c \begin{note} +@c In some implementations the empty list counts as false, contrary +@c to the above. +@c Nonetheless a few examples in this report assume that the +@c empty list counts as true, as in \cite{IEEEScheme}. +@c \end{note} + +@c \begin{rationale} +@c For historical reasons some implementations regard \schfalse{} and the +@c empty list as the same object. These implementations therefore cannot +@c make the empty list count as true in conditional expressions. +@c \end{rationale} + + +@quotation +@emph{Note:} +Programmers accustomed to other dialects of Lisp should be aware that +Scheme distinguishes both @t{#f} and the empty list +@cindex @w{empty list} +from the symbol @code{nil}. +@vindex @w{nil} +@end quotation + + +Boolean constants evaluate to themselves, so they do not need to be quoted +in programs. + + +@example + +#t ==> #t +#f ==> #f +'#f ==> #f + +@end example + + + + +@deffn {library procedure} not obj + +@samp{Not} returns @t{#t} if @var{obj} is false, and returns +@t{#f} otherwise. + + +@format +@t{(not #t) ==> #f +(not 3) ==> #f +(not (list 3)) ==> #f +(not #f) ==> #t +(not '()) ==> #f +(not (list)) ==> #f +(not 'nil) ==> #f +} +@end format + + +@end deffn + + + +@deffn {library procedure} boolean? obj + +@samp{Boolean?} returns @t{#t} if @var{obj} is either @t{#t} or +@t{#f} and returns @t{#f} otherwise. + + +@format +@t{(boolean? #f) ==> #t +(boolean? 0) ==> #f +(boolean? '()) ==> #f +} +@end format + + +@end deffn + + +@node Pairs and lists, Symbols, Booleans, Other data types +@subsection Pairs and lists + + + +A @dfn{pair} (sometimes called a @dfn{dotted pair}) is a +@cindex @w{dotted pair} +@cindex @w{pair} +record structure with two fields called the car and cdr fields (for +historical reasons). Pairs are created by the procedure @samp{cons}. +The car and cdr fields are accessed by the procedures @samp{car} and +@samp{cdr}. The car and cdr fields are assigned by the procedures +@samp{set-car!} and @samp{set-cdr!}. + +Pairs are used primarily to represent lists. A list can +be defined recursively as either the empty list or a pair whose +@cindex @w{empty list} +cdr is a list. More precisely, the set of lists is defined as the smallest +set @var{X} such that + + + +@itemize @bullet + +@item +The empty list is in @var{X}. +@item +If @var{list} is in @var{X}, then any pair whose cdr field contains +@var{list} is also in @var{X}. + +@end itemize + + +The objects in the car fields of successive pairs of a list are the +elements of the list. For example, a two-element list is a pair whose car +is the first element and whose cdr is a pair whose car is the second element +and whose cdr is the empty list. The length of a list is the number of +elements, which is the same as the number of pairs. + +The empty list is a special object of its own type +@cindex @w{empty list} +(it is not a pair); it has no elements and its length is zero. + + +@quotation +@emph{Note:} +The above definitions imply that all lists have finite length and are +terminated by the empty list. +@end quotation + + +The most general notation (external representation) for Scheme pairs is +the ``dotted'' notation @w{@samp{(@var{c1} .@: @var{c2})}} where +@var{c1} is the value of the car field and @var{c2} is the value of the +cdr field. For example @samp{(4 .@: 5)} is a pair whose car is 4 and whose +cdr is 5. Note that @samp{(4 .@: 5)} is the external representation of a +pair, not an expression that evaluates to a pair. + +A more streamlined notation can be used for lists: the elements of the +list are simply enclosed in parentheses and separated by spaces. The +empty list is written @t{()} . For example, +@cindex @w{empty list} + + +@example + +(a b c d e) + +@end example + + +and + + +@example + +(a . (b . (c . (d . (e . ()))))) + +@end example + + +are equivalent notations for a list of symbols. + +A chain of pairs not ending in the empty list is called an +@dfn{improper list}. Note that an improper list is not a list. +@cindex @w{improper list} +The list and dotted notations can be combined to represent +improper lists: + + +@example + +(a b c . d) + +@end example + + +is equivalent to + + +@example + +(a . (b . (c . d))) + +@end example + + +Whether a given pair is a list depends upon what is stored in the cdr +field. When the @code{set-cdr!} procedure is used, an object can be a +@vindex @w{set-cdr!} +list one moment and not the next: + + +@example + +(define x (list 'a 'b 'c)) +(define y x) +y ==> (a b c) +(list? y) ==> #t +(set-cdr! x 4) ==> @emph{unspecified} +x ==> (a . 4) +(eqv? x y) ==> #t +y ==> (a . 4) +(list? y) ==> #f +(set-cdr! x x) ==> @emph{unspecified} +(list? x) ==> #f + +@end example + + +@c It is often convenient to speak of a homogeneous list of objects +@c of some particular data type, as for example \hbox{\cf (1 2 3)} is a list of +@c integers. To be more precise, suppose \var{D} is some data type. (Any +@c predicate defines a data type consisting of those objects of which the +@c predicate is true.) Then + +@c \begin{itemize} +@c \item The empty list is a list of \var{D}. +@c \item If \var{list} is a list of \var{D}, then any pair whose cdr is +@c \var{list} and whose car is an element of the data type \var{D} is also a +@c list of \var{D}. +@c \item There are no other lists of \var{D}. +@c \end{itemize} + +Within literal expressions and representations of objects read by the +@code{read} procedure, the forms @t{'}@r{<datum>}, +@vindex ' +@vindex @w{read} +@t{`}@r{<datum>}, @t{,}@r{<datum>}, and +@vindex , +@t{,@@}@r{<datum>} denote two-ele@-ment lists whose first elements are +the symbols @code{quote}, @code{quasiquote}, @w{@code{unquote}}, and +@vindex @w{unquote} +@vindex @w{quasiquote} +@vindex @w{quote} +@code{unquote-splicing}, respectively. The second element in each case +@vindex @w{unquote-splicing} +is @r{<datum>}. This convention is supported so that arbitrary Scheme +programs may be represented as lists. +@ignore todo +Can or need this be stated +more carefully? +@end ignore + That is, according to Scheme's grammar, every +<expression> is also a <datum> (see section @pxref{External representation}). +Among other things, this permits the use of the @samp{read} procedure to +parse Scheme programs. See section @ref{External representations}. + + + +@deffn {procedure} pair? obj + +@samp{Pair?} returns @t{#t} if @var{obj} is a pair, and otherwise +returns @t{#f}. + + +@format +@t{(pair? '(a . b)) ==> #t +(pair? '(a b c)) ==> #t +(pair? '()) ==> #f +(pair? '#(a b)) ==> #f +} +@end format + +@end deffn + + + +@deffn {procedure} cons obj1 obj2 + +Returns a newly allocated pair whose car is @var{obj1} and whose cdr is +@var{obj2}. The pair is guaranteed to be different (in the sense of +@samp{eqv?}) from every existing object. + + +@format +@t{(cons 'a '()) ==> (a) +(cons '(a) '(b c d)) ==> ((a) b c d) +(cons "a" '(b c)) ==> ("a" b c) +(cons 'a 3) ==> (a . 3) +(cons '(a b) 'c) ==> ((a b) . c) +} +@end format + +@end deffn + + + +@deffn {procedure} car pair + +@ignore nodomain +@var{Pair} must be a pair. +@end ignore + +Returns the contents of the car field of @var{pair}. Note that it is an +error to take the car of the empty list. +@cindex @w{empty list} + + +@format +@t{(car '(a b c)) ==> a +(car '((a) b c d)) ==> (a) +(car '(1 . 2)) ==> 1 +(car '()) ==> @emph{error} +} +@end format + + +@end deffn + + + +@deffn {procedure} cdr pair + +@ignore nodomain +@var{Pair} must be a pair. +@end ignore + +Returns the contents of the cdr field of @var{pair}. +Note that it is an error to take the cdr of the empty list. + + +@format +@t{(cdr '((a) b c d)) ==> (b c d) +(cdr '(1 . 2)) ==> 2 +(cdr '()) ==> @emph{error} +} +@end format + + +@end deffn + + + +@deffn {procedure} set-car! pair obj + +@ignore nodomain +@var{Pair} must be a pair. +@end ignore + +Stores @var{obj} in the car field of @var{pair}. +The value returned by @samp{set-car!} is unspecified. +@c <!> +@c This procedure can be very confusing if used indiscriminately. + + +@format +@t{(define (f) (list 'not-a-constant-list)) +(define (g) '(constant-list)) +(set-car! (f) 3) ==> @emph{unspecified} +(set-car! (g) 3) ==> @emph{error} +} +@end format + + +@end deffn + + + +@deffn {procedure} set-cdr! pair obj + +@ignore nodomain +@var{Pair} must be a pair. +@end ignore + +Stores @var{obj} in the cdr field of @var{pair}. +The value returned by @samp{set-cdr!} is unspecified. +@c <!> +@c This procedure can be very confusing if used indiscriminately. + +@end deffn + + + + + + +@deffn {library procedure} caar pair +@deffnx {library procedure} cadr pair + +@deffnx { @w{ @dots{}}} @w{ @dots{}} + +@deffnx {library procedure} cdddar pair +@deffnx {library procedure} cddddr pair + +These procedures are compositions of @samp{car} and @samp{cdr}, where +for example @samp{caddr} could be defined by + + +@format +@t{(define caddr (lambda (x) (car (cdr (cdr x)))))@r{.} +} +@end format + + +Arbitrary compositions, up to four deep, are provided. There are +twenty-eight of these procedures in all. + +@end deffn + + + +@deffn {library procedure} null? obj + +Returns @t{#t} if @var{obj} is the empty list, +@cindex @w{empty list} +otherwise returns @t{#f}. + +@c \begin{note} +@c In implementations in which the empty +@c list is the same as \schfalse{}, {\cf null?} will return \schtrue{} +@c if \var{obj} is \schfalse{}. +@c \end{note} + +@end deffn + + +@deffn {library procedure} list? obj + +Returns @t{#t} if @var{obj} is a list, otherwise returns @t{#f}. +By definition, all lists have finite length and are terminated by +the empty list. + + +@format +@t{ (list? '(a b c)) ==> #t + (list? '()) ==> #t + (list? '(a . b)) ==> #f + (let ((x (list 'a))) + (set-cdr! x x) + (list? x)) ==> #f +} +@end format + +@end deffn + + + +@deffn {library procedure} list @var{obj} @dots{}, + +Returns a newly allocated list of its arguments. + + +@format +@t{(list 'a (+ 3 4) 'c) ==> (a 7 c) +(list) ==> () +} +@end format + +@end deffn + + + +@deffn {library procedure} length list + +@ignore nodomain +@var{List} must be a list. +@end ignore + +Returns the length of @var{list}. + + +@format +@t{(length '(a b c)) ==> 3 +(length '(a (b) (c d e))) ==> 3 +(length '()) ==> 0 +} +@end format + +@end deffn + + + +@deffn {library procedure} append list @dots{}, + +@ignore nodomain +All @var{list}s should be lists. +@end ignore + +Returns a list consisting of the elements of the first @var{list} +followed by the elements of the other @var{list}s. + + +@format +@t{(append '(x) '(y)) ==> (x y) +(append '(a) '(b c d)) ==> (a b c d) +(append '(a (b)) '((c))) ==> (a (b) (c)) +} +@end format + + +The resulting list is always newly allocated, except that it shares +structure with the last @var{list} argument. The last argument may +actually be any object; an improper list results if the last argument is not a +proper list. +@ignore todo +This is pretty awkward. I should get Bartley to fix this. +@end ignore + + + +@format +@t{(append '(a b) '(c . d)) ==> (a b c . d) +(append '() 'a) ==> a +} +@end format + +@end deffn + + + +@deffn {library procedure} reverse list + +@ignore nodomain +@var{List} must be a list. +@end ignore + +Returns a newly allocated list consisting of the elements of @var{list} +in reverse order. + + +@format +@t{(reverse '(a b c)) ==> (c b a) +(reverse '(a (b c) d (e (f)))) + ==> ((e (f)) d (b c) a) +} +@end format + +@end deffn + + + +@deffn {library procedure} list-tail list @var{k} + +Returns the sublist of @var{list} obtained by omitting the first @var{k} +elements. It is an error if @var{list} has fewer than @var{k} elements. +@samp{List-tail} could be defined by + + +@format +@t{(define list-tail + (lambda (x k) + (if (zero? k) + x + (list-tail (cdr x) (- k 1))))) +} +@end format + +@end deffn + + + +@deffn {library procedure} list-ref list @var{k} + +Returns the @var{k}th element of @var{list}. (This is the same +as the car of @t{(list-tail @var{list} @var{k})}.) +It is an error if @var{list} has fewer than @var{k} elements. + + +@format +@t{(list-ref '(a b c d) 2) ==> c +(list-ref '(a b c d) + (inexact->exact (round 1.8))) + ==> c +} +@end format + +@end deffn + + +@c \begin{entry}{% +@c \proto{last-pair}{ list}{library procedure}} + +@c Returns the last pair in the nonempty, possibly improper, list \var{list}. +@c {\cf Last-pair} could be defined by + +@c \begin{scheme} +@c (define last-pair +@c (lambda (x) +@c (if (pair? (cdr x)) +@c (last-pair (cdr x)) +@c x)))% +@c \end{scheme} + +@c \end{entry} + + + +@deffn {library procedure} memq obj list +@deffnx {library procedure} memv obj list +@deffnx {library procedure} member obj list + +These procedures return the first sublist of @var{list} whose car is +@var{obj}, where the sublists of @var{list} are the non-empty lists +returned by @t{(list-tail @var{list} @var{k})} for @var{k} less +than the length of @var{list}. If +@var{obj} does not occur in @var{list}, then @t{#f} (not the empty list) is +returned. @samp{Memq} uses @samp{eq?} to compare @var{obj} with the elements of +@var{list}, while @samp{memv} uses @samp{eqv?} and @samp{member} uses @samp{equal?}. + + +@format +@t{(memq 'a '(a b c)) ==> (a b c) +(memq 'b '(a b c)) ==> (b c) +(memq 'a '(b c d)) ==> #f +(memq (list 'a) '(b (a) c)) ==> #f +(member (list 'a) + '(b (a) c)) ==> ((a) c) +(memq 101 '(100 101 102)) ==> @emph{unspecified} +(memv 101 '(100 101 102)) ==> (101 102) +} +@end format + + +@end deffn + + + +@deffn {library procedure} assq obj alist +@deffnx {library procedure} assv obj alist +@deffnx {library procedure} assoc obj alist + +@var{Alist} (for ``association list'') must be a list of +pairs. These procedures find the first pair in @var{alist} whose car field is @var{obj}, +and returns that pair. If no pair in @var{alist} has @var{obj} as its +car, then @t{#f} (not the empty list) is returned. @samp{Assq} uses +@samp{eq?} to compare @var{obj} with the car fields of the pairs in @var{alist}, +while @samp{assv} uses @samp{eqv?} and @samp{assoc} uses @samp{equal?}. + + +@format +@t{(define e '((a 1) (b 2) (c 3))) +(assq 'a e) ==> (a 1) +(assq 'b e) ==> (b 2) +(assq 'd e) ==> #f +(assq (list 'a) '(((a)) ((b)) ((c)))) + ==> #f +(assoc (list 'a) '(((a)) ((b)) ((c)))) + ==> ((a)) +(assq 5 '((2 3) (5 7) (11 13))) + ==> @emph{unspecified} +(assv 5 '((2 3) (5 7) (11 13))) + ==> (5 7) +} +@end format + + + + +@quotation +@emph{Rationale:} +Although they are ordinarily used as predicates, +@samp{memq}, @samp{memv}, @samp{member}, @samp{assq}, @samp{assv}, and @samp{assoc} do not +have question marks in their names because they return useful values rather +than just @t{#t} or @t{#f}. +@end quotation + +@end deffn + + +@node Symbols, Characters, Pairs and lists, Other data types +@subsection Symbols + + + +Symbols are objects whose usefulness rests on the fact that two +symbols are identical (in the sense of @samp{eqv?}) if and only if their +names are spelled the same way. This is exactly the property needed to +represent identifiers in programs, and so most +@cindex @w{identifier} +implementations of Scheme use them internally for that purpose. Symbols +are useful for many other applications; for instance, they may be used +the way enumerated values are used in Pascal. + +The rules for writing a symbol are exactly the same as the rules for +writing an identifier; see sections @ref{Identifiers} +and @ref{Lexical structure}. + +It is guaranteed that any symbol that has been returned as part of +a literal expression, or read using the @samp{read} procedure, and +subsequently written out using the @samp{write} procedure, will read back +in as the identical symbol (in the sense of @samp{eqv?}). The +@samp{string->symbol} procedure, however, can create symbols for +which this write/read invariance may not hold because their names +contain special characters or letters in the non-standard case. + + +@quotation +@emph{Note:} +Some implementations of Scheme have a feature known as ``slashification'' +in order to guarantee write/read invariance for all symbols, but +historically the most important use of this feature has been to +compensate for the lack of a string data type. + +Some implementations also have ``uninterned symbols'', which +defeat write/read invariance even in implementations with slashification, +and also generate exceptions to the rule that two symbols are the same +if and only if their names are spelled the same. +@end quotation + + + + +@deffn {procedure} symbol? obj + +Returns @t{#t} if @var{obj} is a symbol, otherwise returns @t{#f}. + + +@format +@t{(symbol? 'foo) ==> #t +(symbol? (car '(a b))) ==> #t +(symbol? "bar") ==> #f +(symbol? 'nil) ==> #t +(symbol? '()) ==> #f +(symbol? #f) ==> #f +} +@end format + +@end deffn + + + +@deffn {procedure} symbol->string symbol + +Returns the name of @var{symbol} as a string. If the symbol was part of +an object returned as the value of a literal expression +(section @pxref{Literal expressions}) or by a call to the @samp{read} procedure, +and its name contains alphabetic characters, then the string returned +will contain characters in the implementation's preferred standard +case---some implementations will prefer upper case, others lower case. +If the symbol was returned by @samp{string->symbol}, the case of +characters in the string returned will be the same as the case in the +string that was passed to @samp{string->symbol}. It is an error +to apply mutation procedures like @code{string-set!} to strings returned +@vindex @w{string-set!} +by this procedure. + +The following examples assume that the implementation's standard case is +lower case: + + +@format +@t{(symbol->string 'flying-fish) + ==> "flying-fish" +(symbol->string 'Martin) ==> "martin" +(symbol->string + (string->symbol "Malvina")) + ==> "Malvina" +} +@end format + +@end deffn + + + +@deffn {procedure} string->symbol string + +Returns 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. See @samp{symbol->string}. + +The following examples assume that the implementation's standard case is +lower case: + + +@format +@t{(eq? 'mISSISSIppi 'mississippi) + ==> #t +(string->symbol "mISSISSIppi") + ==> + @r{}the symbol with name "mISSISSIppi" +(eq? 'bitBlt (string->symbol "bitBlt")) + ==> #f +(eq? 'JollyWog + (string->symbol + (symbol->string 'JollyWog))) + ==> #t +(string=? "K. Harper, M.D." + (symbol->string + (string->symbol "K. Harper, M.D."))) + ==> #t +} +@end format + + +@end deffn + + +@node Characters, Strings, Symbols, Other data types +@subsection Characters + + + +Characters are objects that represent printed characters such as +letters and digits. +@c There is no requirement that the data type of +@c characters be disjoint from other data types; implementations are +@c encouraged to have a separate character data type, but may choose to +@c represent characters as integers, strings, or some other type. +Characters are written using the notation #\@r{<character>} +or #\@r{<character name>}. +For example: + + + +@center @c begin-tabular +@quotation +@table @asis +@item @t{#\a} +; lower case letter +@item @t{#\A} +; upper case letter +@item @t{#\(} +; left parenthesis +@item @t{#\ } +; the space character +@item @t{#\space} +; the preferred way to write a space +@item @t{#\newline} +; the newline character +@item +@end table +@end quotation + + + + +Case is significant in #\@r{<character>}, but not in +#\@r{<character name>}. +@c \hyper doesn't + +@c allow a linebreak +If @r{<character>} in +#\@r{<character>} is alphabetic, then the character +following @r{<character>} must be a delimiter character such as a +space or parenthesis. This rule resolves the ambiguous case where, for +example, the sequence of characters ``@t{#\ space}'' +could be taken to be either a representation of the space character or a +representation of the character ``@t{#\ s}'' followed +by a representation of the symbol ``@t{pace}.'' + +@ignore todo +Fix +@end ignore + +Characters written in the #\ notation are self-evaluating. +That is, they do not have to be quoted in programs. +@c The \sharpsign\backwhack{} +@c notation is not an essential part of Scheme, however. Even implementations +@c that support the \sharpsign\backwhack{} notation for input do not have to +@c support it for output. + +Some of the procedures that operate on characters ignore the +difference between upper case and lower case. The procedures that +ignore case have @w{``@t{-ci}''} (for ``case +insensitive'') embedded in their names. + + + +@deffn {procedure} char? obj + +Returns @t{#t} if @var{obj} is a character, otherwise returns @t{#f}. + +@end deffn + + + +@deffn {procedure} char=? char1 char2 +@deffnx {procedure} char<? char1 char2 +@deffnx {procedure} char>? char1 char2 +@deffnx {procedure} char<=? char1 char2 +@deffnx {procedure} char>=? char1 char2 + + +@ignore nodomain +Both @var{char1} and @var{char2} must be characters. +@end ignore + +These procedures impose a total ordering on the set of characters. It +is guaranteed that under this ordering: + + + +@itemize @bullet + +@item +The upper case characters are in order. For example, @samp{(char<? #\A #\B)} returns @t{#t}. +@item +The lower case characters are in order. For example, @samp{(char<? #\a #\b)} returns @t{#t}. +@item +The digits are in order. For example, @samp{(char<? #\0 #\9)} returns @t{#t}. +@item +Either all the digits precede all the upper case letters, or vice versa. +@item +Either all the digits precede all the lower case letters, or vice versa. + +@end itemize + + +Some implementations may generalize these procedures to take more than +two arguments, as with the corresponding numerical predicates. + +@end deffn + + + +@deffn {library procedure} char-ci=? char1 char2 +@deffnx {library procedure} char-ci<? char1 char2 +@deffnx {library procedure} char-ci>? char1 char2 +@deffnx {library procedure} char-ci<=? char1 char2 +@deffnx {library procedure} char-ci>=? char1 char2 + +@ignore nodomain +Both @var{char1} and @var{char2} must be characters. +@end ignore + +These procedures are similar to @samp{char=?} et cetera, but they treat +upper case and lower case letters as the same. For example, @samp{(char-ci=? #\A #\a)} returns @t{#t}. Some +implementations may generalize these procedures to take more than two +arguments, as with the corresponding numerical predicates. + +@end deffn + + + +@deffn {library procedure} char-alphabetic? char +@deffnx {library procedure} char-numeric? char +@deffnx {library procedure} char-whitespace? char +@deffnx {library procedure} char-upper-case? letter +@deffnx {library procedure} char-lower-case? letter + +These procedures return @t{#t} if their arguments are alphabetic, +numeric, whitespace, upper case, or lower case characters, respectively, +otherwise they return @t{#f}. The following remarks, which are specific to +the ASCII character set, are intended only as a guide: The alphabetic characters +are the 52 upper and lower case letters. The numeric characters are the +ten decimal digits. The whitespace characters are space, tab, line +feed, form feed, and carriage return. +@end deffn + + +@c %R4%%\begin{entry}{% +@c \proto{char-upper-case?}{ letter}{procedure} +@c \proto{char-lower-case?}{ letter}{procedure}} + +@c \domain{\var{Letter} must be an alphabetic character.} +@c These procedures return \schtrue{} if their arguments are upper case or +@c lower case characters, respectively, otherwise they return \schfalse. +@c \end{entry} + + + +@deffn {procedure} char->integer char +@deffnx {procedure} integer->char @var{n} + +Given a character, @samp{char->integer} returns an exact integer +representation of the character. Given an exact integer that is the image of +a character under @samp{char->integer}, @samp{integer->char} +returns that character. These procedures implement order-preserving isomorphisms +between the set of characters under the @code{char<=?} ordering and some +@vindex @w{char<=?} +subset of the integers under the @samp{<=} ordering. That is, if + + +@format +@t{(char<=? @var{a} @var{b}) @result{} #t @r{}and (<= @var{x} @var{y}) @result{} #t +} +@end format + + + +@noindent + and @var{x} and @var{y} are in the domain of +@samp{integer->char}, then + + +@format +@t{(<= (char->integer @var{a}) + (char->integer @var{b})) ==> #t + +(char<=? (integer->char @var{x}) + (integer->char @var{y})) ==> #t +} +@end format + + +@end deffn + + + +@deffn {library procedure} char-upcase char +@deffnx {library procedure} char-downcase char + +@ignore nodomain +@var{Char} must be a character. +@end ignore + +These procedures return a character @var{char2} such that @samp{(char-ci=? @var{char} @var{char2})}. In addition, if @var{char} is +alphabetic, then the result of @samp{char-upcase} is upper case and the +result of @samp{char-downcase} is lower case. + +@end deffn + + +@node Strings, Vectors, Characters, Other data types +@subsection Strings + + + +Strings are sequences of characters. +@c In some implementations of Scheme +@c they are immutable; other implementations provide destructive procedures +@c such as {\cf string-set!}\ that alter string objects. +Strings are written as sequences of characters enclosed within doublequotes +(@samp{"}). A doublequote can be written inside a string only by escaping +it with a backslash (\), as in + + +@example + +"The word \"recursion\" has many meanings." + +@end example + + +A backslash can be written inside a string only by escaping it with another +backslash. Scheme does not specify the effect of a backslash within a +string that is not followed by a doublequote or backslash. + +A string constant may continue from one line to the next, but +the exact contents of such a string are unspecified. +@c this is +@c usually a bad idea because +@c the exact effect may vary from one computer +@c system to another. + +The @emph{length} of a string is the number of characters that it +contains. This number is an exact, non-negative integer that is fixed when the +string is created. The @dfn{valid indexes} of a string are the +@cindex @w{valid indexes} +exact non-negative integers less than the length of the string. The first +character of a string has index 0, the second has index 1, and so on. + +In phrases such as ``the characters of @var{string} beginning with +index @var{start} and ending with index @var{end},'' it is understood +that the index @var{start} is inclusive and the index @var{end} is +exclusive. Thus if @var{start} and @var{end} are the same index, a null +substring is referred to, and if @var{start} is zero and @var{end} is +the length of @var{string}, then the entire string is referred to. + +Some of the procedures that operate on strings ignore the +difference between upper and lower case. The versions that ignore case +have @w{``@samp{-ci}''} (for ``case insensitive'') embedded in their +names. + + + +@deffn {procedure} string? obj + +Returns @t{#t} if @var{obj} is a string, otherwise returns @t{#f}. +@end deffn + + + +@deffn {procedure} make-string @var{k} +@deffnx {procedure} make-string @var{k} char + +@c \domain{\vr{k} must be a non-negative integer, and \var{char} must be +@c a character.} +@samp{Make-string} returns a newly allocated string of +length @var{k}. If @var{char} is given, then all elements of the string +are initialized to @var{char}, otherwise the contents of the +@var{string} are unspecified. + +@end deffn + + +@deffn {library procedure} string char @dots{}, + +Returns a newly allocated string composed of the arguments. + +@end deffn + + +@deffn {procedure} string-length string + +Returns the number of characters in the given @var{string}. +@end deffn + + + +@deffn {procedure} string-ref string @var{k} + +@var{k} must be a valid index of @var{string}. +@samp{String-ref} returns character @var{k} of @var{string} using zero-origin indexing. +@end deffn + + + +@deffn {procedure} string-set! string k char + + +@c \var{String} must be a string, +@var{k} must be a valid index of @var{string} +@c , and \var{char} must be a character +. +@samp{String-set!} stores @var{char} in element @var{k} of @var{string} +and returns an unspecified value. +@c <!> + + +@format +@t{(define (f) (make-string 3 #\*)) +(define (g) "***") +(string-set! (f) 0 #\?) ==> @emph{unspecified} +(string-set! (g) 0 #\?) ==> @emph{error} +(string-set! (symbol->string 'immutable) + 0 + #\?) ==> @emph{error} +} +@end format + + +@end deffn + + + +@deffn {library procedure} string=? string1 string2 +@deffnx {library procedure} string-ci=? string1 string2 + +Returns @t{#t} if the two strings are the same length and contain the same +characters in the same positions, otherwise returns @t{#f}. +@samp{String-ci=?} treats +upper and lower case letters as though they were the same character, but +@samp{string=?} treats upper and lower case as distinct characters. + +@end deffn + + + +@deffn {library procedure} string<? string1 string2 +@deffnx {library procedure} string>? string1 string2 +@deffnx {library procedure} string<=? string1 string2 +@deffnx {library procedure} string>=? string1 string2 +@deffnx {library procedure} string-ci<? string1 string2 +@deffnx {library procedure} string-ci>? string1 string2 +@deffnx {library procedure} string-ci<=? string1 string2 +@deffnx {library procedure} string-ci>=? string1 string2 + +These procedures are the lexicographic extensions to strings of the +corresponding orderings on characters. For example, @samp{string<?} is +the lexicographic ordering on strings induced by the ordering +@samp{char<?} on characters. If two strings differ in length but +are the same up to the length of the shorter string, the shorter string +is considered to be lexicographically less than the longer string. + +Implementations may generalize these and the @samp{string=?} and +@samp{string-ci=?} procedures to take more than two arguments, as with +the corresponding numerical predicates. + +@end deffn + + + +@deffn {library procedure} substring string start end + +@var{String} must be a string, and @var{start} and @var{end} +must be exact integers satisfying + + +@center 0 <= @var{start} <= @var{end} <= @w{@t{(string-length @var{string})@r{.}}} + +@samp{Substring} returns a newly allocated string formed from the characters of +@var{string} beginning with index @var{start} (inclusive) and ending with index +@var{end} (exclusive). +@end deffn + + + +@deffn {library procedure} string-append @var{string} @dots{}, + +Returns a newly allocated string whose characters form the concatenation of the +given strings. + +@end deffn + + + +@deffn {library procedure} string->list string +@deffnx {library procedure} list->string list + +@samp{String->list} returns a newly allocated list of the +characters that make up the given string. @samp{List->string} +returns a newly allocated string formed from the characters in the list +@var{list}, which must be a list of characters. @samp{String->list} +and @samp{list->string} are +inverses so far as @samp{equal?} is concerned. +@c Implementations that provide +@c destructive operations on strings should ensure that the result of +@c {\cf list\coerce{}string} is newly allocated. + +@end deffn + + + +@deffn {library procedure} string-copy string + +Returns a newly allocated copy of the given @var{string}. + +@end deffn + + + +@deffn {library procedure} string-fill! string char + +Stores @var{char} in every element of the given @var{string} and returns an +unspecified value. +@c <!> + +@end deffn + + +@node Vectors, , Strings, Other data types +@subsection Vectors + + + +Vectors are heterogenous structures whose elements are indexed +by integers. A vector typically occupies less space than a list +of the same length, and the average time required to access a randomly +chosen element is typically less for the vector than for the list. + +The @emph{length} of a vector is the number of elements that it +contains. This number is a non-negative integer that is fixed when the +vector is created. The @emph{valid indexes} of a +@cindex @w{valid indexes} +vector are the exact non-negative integers less than the length of the +vector. The first element in a vector is indexed by zero, and the last +element is indexed by one less than the length of the vector. + +Vectors are written using the notation @t{#(@var{obj} @dots{},)}. +For example, a vector of length 3 containing the number zero in element +0, the list @samp{(2 2 2 2)} in element 1, and the string @samp{"Anna"} in +element 2 can be written as following: + + +@example + +#(0 (2 2 2 2) "Anna") + +@end example + + +Note that this is the external representation of a vector, not an +expression evaluating to a vector. Like list constants, vector +constants must be quoted: + + +@example + +'#(0 (2 2 2 2) "Anna") + ==> #(0 (2 2 2 2) "Anna") + +@end example + + +@ignore todo +Pitman sez: The visual similarity to lists is bound to be confusing +to some. Elaborate on the distinction. +@end ignore + + + + +@deffn {procedure} vector? obj + +Returns @t{#t} if @var{obj} is a vector, otherwise returns @t{#f}. +@end deffn + + + +@deffn {procedure} make-vector k +@deffnx {procedure} make-vector k fill + +Returns a newly allocated vector of @var{k} elements. If a second +argument is given, then each element is initialized to @var{fill}. +Otherwise the initial contents of each element is unspecified. + +@end deffn + + + +@deffn {library procedure} vector obj @dots{}, + +Returns a newly allocated vector whose elements contain the given +arguments. Analogous to @samp{list}. + + +@format +@t{(vector 'a 'b 'c) ==> #(a b c) +} +@end format + +@end deffn + + + +@deffn {procedure} vector-length vector + +Returns the number of elements in @var{vector} as an exact integer. +@end deffn + + + +@deffn {procedure} vector-ref vector k + +@var{k} must be a valid index of @var{vector}. +@samp{Vector-ref} returns the contents of element @var{k} of +@var{vector}. + + +@format +@t{(vector-ref '#(1 1 2 3 5 8 13 21) + 5) + ==> 8 +(vector-ref '#(1 1 2 3 5 8 13 21) + (let ((i (round (* 2 (acos -1))))) + (if (inexact? i) + (inexact->exact i) + i))) + ==> 13 +} +@end format + +@end deffn + + + +@deffn {procedure} vector-set! vector k obj + +@var{k} must be a valid index of @var{vector}. +@samp{Vector-set!} stores @var{obj} in element @var{k} of @var{vector}. +The value returned by @samp{vector-set!} is unspecified. +@c <!> + + +@format +@t{(let ((vec (vector 0 '(2 2 2 2) "Anna"))) + (vector-set! vec 1 '("Sue" "Sue")) + vec) + ==> #(0 ("Sue" "Sue") "Anna") + +(vector-set! '#(0 1 2) 1 "doe") + ==> @emph{error} ; constant vector +} +@end format + +@end deffn + + + +@deffn {library procedure} vector->list vector +@deffnx {library procedure} list->vector list + +@samp{Vector->list} returns a newly allocated list of the objects contained +in the elements of @var{vector}. @samp{List->vector} returns a newly +created vector initialized to the elements of the list @var{list}. + + +@format +@t{(vector->list '#(dah dah didah)) + ==> (dah dah didah) +(list->vector '(dididit dah)) + ==> #(dididit dah) +} +@end format + +@end deffn + + + +@deffn {library procedure} vector-fill! vector fill + +Stores @var{fill} in every element of @var{vector}. +The value returned by @samp{vector-fill!} is unspecified. +@c <!> + +@end deffn + + +@node Control features, Eval, Other data types, Standard procedures +@section Control features + + + +@c Intro flushed; not very a propos any more. +@c Procedures should be discussed somewhere, however. + +This chapter describes various primitive procedures which control the +flow of program execution in special ways. +The @samp{procedure?} predicate is also described here. + +@ignore todo +@t{Procedure?} doesn't belong in a section with the name +``control features.'' What to do? +@end ignore + + + +@deffn {procedure} procedure? obj + +Returns @t{#t} if @var{obj} is a procedure, otherwise returns @t{#f}. + + +@format +@t{(procedure? car) ==> #t +(procedure? 'car) ==> #f +(procedure? (lambda (x) (* x x))) + ==> #t +(procedure? '(lambda (x) (* x x))) + ==> #f +(call-with-current-continuation procedure?) + ==> #t +} +@end format + + +@end deffn + + + +@deffn {procedure} apply proc arg1 @dots{} args + +@var{Proc} must be a procedure and @var{args} must be a list. +Calls @var{proc} with the elements of the list +@samp{(append (list @var{arg1} @dots{},) @var{args})} as the actual +arguments. + + +@format +@t{(apply + (list 3 4)) ==> 7 + +(define compose + (lambda (f g) + (lambda args + (f (apply g args))))) + +((compose sqrt *) 12 75) ==> 30 +} +@end format + +@end deffn + + + +@deffn {library procedure} map proc list1 list2 @dots{}, + +The @var{list}s must be lists, and @var{proc} must be a +procedure taking as many arguments as there are @i{list}s +and returning a single value. If more +than one @var{list} is given, then they must all be the same length. +@samp{Map} applies @var{proc} element-wise to the elements of the +@var{list}s and returns a list of the results, in order. +The dynamic order in which @var{proc} is applied to the elements of the +@var{list}s is unspecified. + + +@format +@t{(map cadr '((a b) (d e) (g h))) + ==> (b e h) + +(map (lambda (n) (expt n n)) + '(1 2 3 4 5)) + ==> (1 4 27 256 3125) + +(map + '(1 2 3) '(4 5 6)) ==> (5 7 9) + +(let ((count 0)) + (map (lambda (ignored) + (set! count (+ count 1)) + count) + '(a b))) ==> (1 2) @var{or} (2 1) +} +@end format + + +@end deffn + + + +@deffn {library procedure} for-each proc list1 list2 @dots{}, + +The arguments to @samp{for-each} are like the arguments to @samp{map}, but +@samp{for-each} calls @var{proc} for its side effects rather than for its +values. Unlike @samp{map}, @samp{for-each} is guaranteed to call @var{proc} on +the elements of the @var{list}s in order from the first element(s) to the +last, and the value returned by @samp{for-each} is unspecified. + + +@format +@t{(let ((v (make-vector 5))) + (for-each (lambda (i) + (vector-set! v i (* i i))) + '(0 1 2 3 4)) + v) ==> #(0 1 4 9 16) +} +@end format + + +@end deffn + + + +@deffn {library procedure} force promise + +Forces the value of @var{promise} (see @code{delay}, +@vindex @w{delay} +section @pxref{Delayed evaluation}). If no value has been computed for +@cindex @w{promise} +the promise, then a value is computed and returned. The value of the +promise is cached (or ``memoized'') so that if it is forced a second +time, the previously computed value is returned. +@c without any recomputation. +@c [As pointed out by Marc Feeley, the "without any recomputation" +@c isn't necessarily true. --Will] + + +@format +@t{(force (delay (+ 1 2))) ==> 3 +(let ((p (delay (+ 1 2)))) + (list (force p) (force p))) + ==> (3 3) + +(define a-stream + (letrec ((next + (lambda (n) + (cons n (delay (next (+ n 1))))))) + (next 0))) +(define head car) +(define tail + (lambda (stream) (force (cdr stream)))) + +(head (tail (tail a-stream))) + ==> 2 +} +@end format + + +@samp{Force} and @samp{delay} are mainly intended for programs written in +functional style. The following examples should not be considered to +illustrate good programming style, but they illustrate the property that +only one value is computed for a promise, no matter how many times it is +forced. +@c the value of a promise is computed at most once. +@c [As pointed out by Marc Feeley, it may be computed more than once, +@c but as I observed we can at least insist that only one value be +@c used! -- Will] + + +@format +@t{(define count 0) +(define p + (delay (begin (set! count (+ count 1)) + (if (> count x) + count + (force p))))) +(define x 5) +p ==> @i{}a promise +(force p) ==> 6 +p ==> @i{}a promise, still +(begin (set! x 10) + (force p)) ==> 6 +} +@end format + + +Here is a possible implementation of @samp{delay} and @samp{force}. +Promises are implemented here as procedures of no arguments, +and @samp{force} simply calls its argument: + + +@format +@t{(define force + (lambda (object) + (object))) +} +@end format + + +We define the expression + + +@format +@t{(delay @r{<expression>}) +} +@end format + + +to have the same meaning as the procedure call + + +@format +@t{(make-promise (lambda () @r{<expression>}))@r{} +} +@end format + + +as follows + + +@format +@t{(define-syntax delay + (syntax-rules () + ((delay expression) + (make-promise (lambda () expression))))), +} +@end format + + +where @samp{make-promise} is defined as follows: + +@c \begin{scheme} +@c (define make-promise +@c (lambda (proc) +@c (let ((already-run? \schfalse) (result \schfalse)) +@c (lambda () +@c (cond ((not already-run?) +@c (set! result (proc)) +@c (set! already-run? \schtrue))) +@c result))))% +@c \end{scheme} + + +@format +@t{(define make-promise + (lambda (proc) + (let ((result-ready? #f) + (result #f)) + (lambda () + (if result-ready? + result + (let ((x (proc))) + (if result-ready? + result + (begin (set! result-ready? #t) + (set! result x) + result)))))))) +} +@end format + + + +@quotation +@emph{Rationale:} +A promise may refer to its own value, as in the last example above. +Forcing such a promise may cause the promise to be forced a second time +before the value of the first force has been computed. +This complicates the definition of @samp{make-promise}. +@end quotation + + +Various extensions to this semantics of @samp{delay} and @samp{force} +are supported in some implementations: + + + +@itemize @bullet + +@item +Calling @samp{force} on an object that is not a promise may simply +return the object. + +@item +It may be the case that there is no means by which a promise can be +operationally distinguished from its forced value. That is, expressions +like the following may evaluate to either @t{#t} or to @t{#f}, +depending on the implementation: + + +@format +@t{(eqv? (delay 1) 1) ==> @emph{unspecified} +(pair? (delay (cons 1 2))) ==> @emph{unspecified} +} +@end format + + +@item +Some implementations may implement ``implicit forcing,'' where +the value of a promise is forced by primitive procedures like @samp{cdr} +and @samp{+}: + + +@format +@t{(+ (delay (* 3 7)) 13) ==> 34 +} +@end format + + +@end itemize + +@end deffn + + +@deffn {procedure} call-with-current-continuation proc + + @var{Proc} must be a procedure of one +argument. The procedure @samp{call-with-current-continuation} packages +up the current continuation (see the rationale below) as an ``escape +procedure'' and passes it as an argument to +@cindex @w{escape procedure} +@var{proc}. The escape procedure is a Scheme procedure that, if it is +later called, will abandon whatever continuation is in effect at that later +time and will instead use the continuation that was in effect +when the escape procedure was created. Calling the escape procedure +may cause the invocation of @var{before} and @var{after} thunks installed using +@code{dynamic-wind}. +@vindex @w{dynamic-wind} + +The escape procedure accepts the same number of arguments as the continuation to +the original call to @t{call-with-current-continuation}. +Except for continuations created by the @samp{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 @t{call-with-values} is unspecified. + +The escape procedure that is passed to @var{proc} has +unlimited extent just like any other procedure in Scheme. It may be stored +in variables or data structures and may be called as many times as desired. + +The following examples show only the most common ways in which +@samp{call-with-current-continuation} is used. If all real uses were as +simple as these examples, there would be no need for a procedure with +the power of @samp{call-with-current-continuation}. + + +@format +@t{(call-with-current-continuation + (lambda (exit) + (for-each (lambda (x) + (if (negative? x) + (exit x))) + '(54 0 37 -3 245 19)) + #t)) ==> -3 + +(define list-length + (lambda (obj) + (call-with-current-continuation + (lambda (return) + (letrec ((r + (lambda (obj) + (cond ((null? obj) 0) + ((pair? obj) + (+ (r (cdr obj)) 1)) + (else (return #f)))))) + (r obj)))))) + +(list-length '(1 2 3 4)) ==> 4 + +(list-length '(a b . c)) ==> #f +} +@end format + + + +@quotation +@emph{Rationale:} + +A common use of @samp{call-with-current-continuation} is for +structured, non-local exits from loops or procedure bodies, but in fact +@samp{call-with-current-continuation} is extremely useful for implementing a +wide variety of advanced control structures. + +Whenever a Scheme expression is evaluated there is a +@dfn{continuation} wanting the result of the expression. The continuation +@cindex @w{continuation} +represents an entire (default) future for the computation. If the expression is +evaluated at top level, for example, then the continuation might take the +result, print it on the screen, prompt for the next input, evaluate it, and +so on forever. Most of the time the continuation includes actions +specified by user code, as in a continuation that will take the result, +multiply it by the value stored in a local variable, add seven, and give +the answer to the top level continuation to be printed. Normally these +ubiquitous continuations are hidden behind the scenes and programmers do not +think much about them. On rare occasions, however, a programmer may +need to deal with continuations explicitly. +@samp{Call-with-current-continuation} allows Scheme programmers to do +that by creating a procedure that acts just like the current +continuation. + +Most programming languages incorporate one or more special-purpose +escape constructs with names like @t{exit}, @w{@samp{return}}, or +even @t{goto}. In 1965, however, Peter Landin [Landin65] +invented a general purpose escape operator called the J-operator. John +Reynolds [Reynolds72] described a simpler but equally powerful +construct in 1972. The @samp{catch} special form described by Sussman +and Steele in the 1975 report on Scheme is exactly the same as +Reynolds's construct, though its name came from a less general construct +in MacLisp. Several Scheme implementors noticed that the full power of the +@code{catch} construct could be provided by a procedure instead of by a +@vindex @w{catch} +special syntactic construct, and the name +@samp{call-with-current-continuation} was coined in 1982. This name is +descriptive, but opinions differ on the merits of such a long name, and +some people use the name @code{call/cc} instead. +@vindex @w{call/cc} +@end quotation + + +@end deffn + + +@deffn {procedure} values obj @dots{} + +Delivers all of its arguments to its continuation. +Except for continuations created by the @code{call-with-values} +@vindex @w{call-with-values} +procedure, all continuations take exactly one value. +@t{Values} might be defined as follows: + +@format +@t{(define (values . things) + (call-with-current-continuation + (lambda (cont) (apply cont things)))) +} +@end format + + +@end deffn + + +@deffn {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 @t{call-with-values}. + + +@format +@t{(call-with-values (lambda () (values 4 5)) + (lambda (a b) b)) + ==> 5 + +(call-with-values * -) ==> -1 +} +@end format + + +@end deffn + + +@deffn {procedure} dynamic-wind before thunk after + +Calls @var{thunk} without arguments, returning the result(s) of this call. +@var{Before} and @var{after} are called, also without arguments, as required +by the following rules (note that in the absence of calls to continuations +captured using @code{call-with-current-continuation} the three arguments are +@vindex @w{call-with-current-continuation} +called once each, in order). @var{Before} is called whenever execution +enters the dynamic extent of the call to @var{thunk} and @var{after} is called +whenever it exits that dynamic extent. The dynamic extent of a procedure +call is the period between when the call is initiated and when it +returns. In Scheme, because of @samp{call-with-current-continuation}, the +dynamic extent of a call may not be a single, connected time period. +It is defined as follows: + + +@itemize @bullet + +@item +The dynamic extent is entered when execution of the body of the +called procedure begins. + +@item +The dynamic extent is also entered when execution is not within +the dynamic extent and a continuation is invoked that was captured +(using @samp{call-with-current-continuation}) during the dynamic extent. + +@item +It is exited when the called procedure returns. + +@item +It is also exited when execution is within the dynamic extent and +a continuation is invoked that was captured while not within the +dynamic extent. + +@end itemize + + +If a second call to @samp{dynamic-wind} occurs within the dynamic extent of the +call to @var{thunk} and then a continuation is invoked in such a way that the +@var{after}s from these two invocations of @samp{dynamic-wind} are both to be +called, then the @var{after} associated with the second (inner) call to +@samp{dynamic-wind} is called first. + +If a second call to @samp{dynamic-wind} occurs within the dynamic extent of the +call to @var{thunk} and then a continuation is invoked in such a way that the +@var{before}s from these two invocations of @samp{dynamic-wind} are both to be +called, then the @var{before} associated with the first (outer) call to +@samp{dynamic-wind} is called first. + +If invoking a continuation requires calling the @var{before} from one call +to @samp{dynamic-wind} and the @var{after} from another, then the @var{after} +is called first. + +The effect of using a captured continuation to enter or exit the dynamic +extent of a call to @var{before} or @var{after} is undefined. + + +@format +@t{(let ((path '()) + (c #f)) + (let ((add (lambda (s) + (set! path (cons s path))))) + (dynamic-wind + (lambda () (add 'connect)) + (lambda () + (add (call-with-current-continuation + (lambda (c0) + (set! c c0) + 'talk1)))) + (lambda () (add 'disconnect))) + (if (< (length path) 4) + (c 'talk2) + (reverse path)))) + + ==> (connect talk1 disconnect + connect talk2 disconnect) +} +@end format + +@end deffn + +@node Eval, Input and output, Control features, Standard procedures +@section Eval + + + +@deffn {procedure} eval expression environment-specifier + +Evaluates @var{expression} in the specified environment and returns its value. +@var{Expression} must be a valid Scheme expression represented as data, +and @var{environment-specifier} must be a value returned by one of the +three procedures described below. +Implementations may extend @samp{eval} to allow non-expression programs +(definitions) as the first argument and to allow other +values as environments, with the restriction that @samp{eval} is not +allowed to create new bindings in the environments associated with +@samp{null-environment} or @samp{scheme-report-environment}. + + +@format +@t{(eval '(* 7 3) (scheme-report-environment 5)) + ==> 21 + +(let ((f (eval '(lambda (f x) (f x x)) + (null-environment 5)))) + (f + 10)) + ==> 20 +} +@end format + + +@end deffn + + +@deffn {procedure} scheme-report-environment version +@deffnx {procedure} null-environment version + +@var{Version} must be the exact integer @samp{5}, +corresponding to this revision of the Scheme report (the +Revised^5 Report on Scheme). +@samp{Scheme-report-environment} returns a specifier for an +environment that is empty except for all bindings defined in +this report that are either required or both optional and +supported by the implementation. @samp{Null-environment} returns +a specifier for an environment that is empty except for the +(syntactic) bindings for all syntactic keywords defined in +this report that are either required or both optional and +supported by the implementation. + +Other values of @var{version} can be used to specify environments +matching past revisions of this report, but their support is not +required. An implementation will signal an error if @var{version} +is neither @samp{5} nor another value supported by +the implementation. + +The effect of assigning (through the use of @samp{eval}) a variable +bound in a @samp{scheme-report-environment} +(for example @samp{car}) is unspecified. Thus the environments specified +by @samp{scheme-report-environment} may be immutable. + +@end deffn + + +@deffn {optional procedure} interaction-environment + +This procedure returns a specifier for the environment that +contains imple@-men@-ta@-tion-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 + +@node Input and output, , Eval, Standard procedures +@section Input and output + +@menu +* Ports:: +* Input:: +* Output:: +* System interface:: +@end menu + + +@node Ports, Input, Input and output, Input and output +@subsection Ports + + + +Ports represent input and output devices. To Scheme, an input port is a +Scheme object that can deliver characters upon command, while an output port +is a Scheme object that can accept characters. +@cindex @w{port} + +@ignore todo +Haase: Mention that there are alternatives to files? +@end ignore + + + +@deffn {library procedure} call-with-input-file string proc +@deffnx {library procedure} call-with-output-file string proc + +@var{String} should be a string naming a file, and +@var{proc} should be a procedure that accepts one argument. +For @samp{call-with-input-file}, +the file should already exist; for +@samp{call-with-output-file}, +the effect is unspecified if the file +already exists. These procedures call @var{proc} with one argument: the +port obtained by opening the named file for input or output. If the +file cannot be opened, an error is signalled. If @var{proc} returns, +then the port is closed automatically and the value(s) yielded by the +@var{proc} is(are) returned. If @var{proc} does not return, then +the port will not be closed automatically unless it is possible to +prove that the port will never again be used for a read or write +operation. +@c Scheme +@c will not close the port unless it can prove that the port will never +@c again be used for a read or write operation. + + +@quotation +@emph{Rationale:} +Because Scheme's escape procedures have unlimited extent, it is +possible to escape from the current continuation but later to escape back in. +If implementations were permitted to close the port on any escape from the +current continuation, then it would be impossible to write portable code using +both @samp{call-with-current-continuation} and @samp{call-with-input-file} or +@samp{call-with-output-file}. +@ignore todo +Pitman wants more said here; maybe encourage users to call +@var{close-foo-port}; maybe talk about process switches (?). +@end ignore + +@end quotation + +@end deffn + + + +@deffn {procedure} input-port? obj +@deffnx {procedure} output-port? obj + +Returns @t{#t} if @var{obj} is an input port or output port +respectively, otherwise returns @t{#f}. + +@ignore todo +Won't necessarily return true after port is closed. +@end ignore + + +@end deffn + + + +@deffn {procedure} current-input-port +@deffnx {procedure} current-output-port + +Returns the current default input or output port. + +@end deffn + + + +@deffn {optional procedure} with-input-from-file string thunk +@deffnx {optional procedure} with-output-to-file string thunk + +@var{String} should be a string naming a file, and +@var{proc} should be a procedure of no arguments. +For @samp{with-input-from-file}, +the file should already exist; for +@samp{with-output-to-file}, +the effect is unspecified if the file +already exists. +The file is opened for input or output, an input or output port +connected to it is made the default value returned by +@samp{current-input-port} or @samp{current-output-port} +(and is used by @t{(read)}, @t{(write @var{obj})}, and so forth), +and the +@var{thunk} is called with no arguments. When the @var{thunk} returns, +the port is closed and the previous default is restored. +@samp{With-input-from-file} and @samp{with-output-to-file} return(s) the +value(s) yielded by @var{thunk}. +If an escape procedure +is used to escape from the continuation of these procedures, their +behavior is implementation dependent. + +@ignore todo +OK this with authors?? +@end ignore + +@c current continuation changes in such a way +@c as to make it doubtful that the \var{thunk} will ever return. + +@ignore todo +Freeman: +Throughout this section I wanted to see ``the value of @t{(current-input-port)}'' +instead of ``the value returned by @var{current-input-port}''. (Same for +@var{current-output-port}.) +@end ignore + + + +@end deffn + + + +@deffn {procedure} open-input-file filename + +Takes a string naming an existing file and returns an input port capable of +delivering characters from the file. If the file cannot be opened, an error is +signalled. + +@end deffn + + + +@deffn {procedure} open-output-file filename + +Takes a string naming an output file to be created and returns an output +port capable of writing characters to a new file by that name. If the file +cannot be opened, an error is signalled. If a file with the given name +already exists, the effect is unspecified. + +@end deffn + + + +@deffn {procedure} close-input-port port +@deffnx {procedure} close-output-port port + +Closes the file associated with @var{port}, rendering the @var{port} +incapable of delivering or accepting characters. +@ignore todo +But maybe a no-op +on some ports, e.g. terminals or editor buffers. +@end ignore + +These routines have no effect if the file has already been closed. +The value returned is unspecified. + +@ignore todo +Ramsdell: Some note is needed explaining why there are two +different close procedures. +@end ignore + + +@ignore todo +A port isn't necessarily still a port after it has been closed? +@end ignore + + +@end deffn + + +@node Input, Output, Ports, Input and output +@subsection Input + + + + +@noindent + @w{ } +@c ??? +@sp 5 +@ignore todo +The input routines have some things in common, maybe explain here. +@end ignore + + + +@deffn {library procedure} read +@deffnx {library procedure} read port + +@samp{Read} converts external representations of Scheme objects into the +objects themselves. That is, it is a parser for the nonterminal +<datum> (see sections @pxref{External representation} and +@pxref{Pairs and lists}). @samp{Read} returns the next +object parsable from the given input @var{port}, updating @var{port} to point to +the first character past the end of the external representation of the object. + +If an end of file is encountered in the input before any +characters are found that can begin an object, then an end of file +object is returned. +@ignore todo + +@end ignore + The port remains open, and further attempts +to read will also return an end of file object. If an end of file is +encountered after the beginning of an object's external representation, +but the external representation is incomplete and therefore not parsable, +an error is signalled. + +The @var{port} argument may be omitted, in which case it defaults to the +value returned by @samp{current-input-port}. It is an error to read from +a closed port. +@end deffn + + +@deffn {procedure} read-char +@deffnx {procedure} read-char port + +Returns the next character available from the input @var{port}, updating +the @var{port} to point to the following character. If no more characters +are available, an end of file object is returned. @var{Port} may be +omitted, in which case it defaults to the value returned by @samp{current-input-port}. + +@end deffn + + + +@deffn {procedure} peek-char +@deffnx {procedure} peek-char port + +Returns the next character available from the input @var{port}, +@emph{without} updating +the @var{port} to point to the following character. If no more characters +are available, an end of file object is returned. @var{Port} may be +omitted, in which case it defaults to the value returned by @samp{current-input-port}. + + +@quotation +@emph{Note:} +The value returned by a call to @samp{peek-char} is the same as the +value that would have been returned by a call to @samp{read-char} with the +same @var{port}. The only difference is that the very next call to +@samp{read-char} or @samp{peek-char} on that @var{port} will return the +value returned by the preceding call to @samp{peek-char}. In particular, a call +to @samp{peek-char} on an interactive port will hang waiting for input +whenever a call to @samp{read-char} would have hung. +@end quotation + + +@end deffn + + + +@deffn {procedure} eof-object? obj + +Returns @t{#t} if @var{obj} is an end of file object, otherwise returns +@t{#f}. The precise set of end of file objects will vary among +implementations, but in any case no end of file object will ever be an object +that can be read in using @samp{read}. + +@end deffn + + + +@deffn {procedure} char-ready? +@deffnx {procedure} char-ready? port + +Returns @t{#t} if a character is ready on the input @var{port} and +returns @t{#f} otherwise. If @samp{char-ready} returns @t{#t} then +the next @samp{read-char} operation on the given @var{port} is guaranteed +not to hang. If the @var{port} is at end of file then @samp{char-ready?} +returns @t{#t}. @var{Port} may be omitted, in which case it defaults to +the value returned by @samp{current-input-port}. + + +@quotation +@emph{Rationale:} +@samp{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 ensure that +characters whose existence has been asserted by @samp{char-ready?} cannot +be rubbed out. If @samp{char-ready?} were to return @t{#f} at end of +file, a port at end of file would be indistinguishable from an interactive +port that has no ready characters. +@end quotation + +@end deffn + + +@node Output, System interface, Input, Input and output +@subsection Output + + + +@c We've got to put something here to fix the indentation!! + +@noindent + @w{} +@sp 5 + + +@deffn {library procedure} write obj +@deffnx {library procedure} write obj port + +Writes a written representation of @var{obj} to the given @var{port}. Strings +that appear in the written representation are enclosed in doublequotes, and +within those strings backslash and doublequote characters are +escaped by backslashes. +Character objects are written using the @samp{#\} notation. +@samp{Write} returns an unspecified value. The +@var{port} argument may be omitted, in which case it defaults to the value +returned by @samp{current-output-port}. + +@end deffn + + + +@deffn {library procedure} display obj +@deffnx {library procedure} display obj port + +Writes a representation of @var{obj} to the given @var{port}. Strings +that appear in the written representation are not enclosed in +doublequotes, and no characters are escaped within those strings. Character +objects appear in the representation as if written by @samp{write-char} +instead of by @samp{write}. @samp{Display} returns an unspecified value. +The @var{port} argument may be omitted, in which case it defaults to the +value returned by @samp{current-output-port}. + + +@quotation +@emph{Rationale:} +@samp{Write} is intended +for producing mach@-ine-readable output and @samp{display} is for producing +human-readable output. Implementations that allow ``slashification'' +within symbols will probably want @samp{write} but not @samp{display} to +slashify funny characters in symbols. +@end quotation + +@end deffn + + + +@deffn {library procedure} newline +@deffnx {library procedure} newline port + +Writes an end of line to @var{port}. Exactly how this is done differs +from one operating system to another. Returns an unspecified value. +The @var{port} argument may be omitted, in which case it defaults to the +value returned by @samp{current-output-port}. + +@end deffn + + + +@deffn {procedure} write-char char +@deffnx {procedure} write-char char port + +Writes the character @var{char} (not an external representation of the +character) to the given @var{port} and returns an unspecified value. The +@var{port} argument may be omitted, in which case it defaults to the value +returned by @samp{current-output-port}. + +@end deffn + + +@node System interface, , Output, Input and output +@subsection System interface + + +Questions of system interface generally fall outside of the domain of this +report. However, the following operations are important enough to +deserve description here. + + + +@deffn {optional procedure} load filename + +@ignore todo +Fix +@end ignore + + +@c \domain{\var{Filename} should be a string naming an existing file +@c containing Scheme source code.} The {\cf load} procedure reads +@var{Filename} should be a string naming an existing file +containing Scheme source code. The @samp{load} procedure reads +expressions and definitions from the file and evaluates them +sequentially. It is unspecified whether the results of the expressions +are printed. The @samp{load} procedure does not affect the values +returned by @samp{current-input-port} and @samp{current-output-port}. +@samp{Load} returns an unspecified value. + + +@quotation +@emph{Rationale:} +For portability, @samp{load} must operate on source files. +Its operation on other kinds of files necessarily varies among +implementations. +@end quotation + +@end deffn + + + +@deffn {optional procedure} transcript-on filename +@deffnx {optional procedure} transcript-off + +@var{Filename} must be a string naming an output file to be +created. The effect of @samp{transcript-on} is to open the named file +for output, and to cause a transcript of subsequent interaction between +the user and the Scheme system to be written to the file. The +transcript is ended by a call to @samp{transcript-off}, which closes the +transcript file. Only one transcript may be in progress at any time, +though some implementations may relax this restriction. The values +returned by these procedures are unspecified. + +@c \begin{note} +@c These procedures are redundant in some systems, but +@c systems that need them should provide them. +@c \end{note} +@end deffn + +@page + +@c @include{syn} +@node Formal syntax and semantics, Notes, Standard procedures, top +@chapter Formal syntax and semantics + +@menu +* Formal syntax:: +* Formal semantics:: +* Derived expression type:: +@end menu + + + +This chapter provides formal descriptions of what has already been +described informally in previous chapters of this report. + +@ignore todo +Allow grammar to say that else clause needn't be last? +@end ignore + + + +@node Formal syntax, Formal semantics, Formal syntax and semantics, Formal syntax and semantics +@section Formal syntax + +@menu +* Lexical structure:: +* External representation:: +* Expression:: +* Quasiquotations:: +* Transformers:: +* Programs and definitions:: +@end menu + + + +This section provides a formal syntax for Scheme written in an extended +BNF. + +All spaces in the grammar are for legibility. Case is insignificant; +for example, @samp{#x1A} and @samp{#X1a} are equivalent. <empty> +stands for the empty string. + +The following extensions to BNF are used to make the description more +concise: <thing>* means zero or more occurrences of +<thing>; and <thing>+ means at least one +<thing>. + + +@node Lexical structure, External representation, Formal syntax, Formal syntax +@subsection Lexical structure + + +This section describes how individual tokens (identifiers, +@cindex @w{token} +numbers, etc.) are formed from sequences of characters. The following +sections describe how expressions and programs are formed from sequences +of tokens. + +<Intertoken space> may occur on either side of any token, but not +within a token. + +Tokens which require implicit termination (identifiers, numbers, +characters, and dot) may be terminated by any <delimiter>, but not +necessarily by anything else. + +The following five characters are reserved for future extensions to the +language: @t{[ ] @{ @} |} + + +@format +@t{<token> --> <identifier> | <boolean> | <number> +@cindex @w{identifier} + | <character> | <string> + | ( | ) | #( | @t{'} | @t{`} | , | ,@@ | @b{.} +<delimiter> --> <whitespace> | ( | ) | " | ; +<whitespace> --> <space or newline> +<comment> --> ; <@r{all subsequent characters up to a} + @r{line break>} +@cindex @w{comment} +<atmosphere> --> <whitespace> | <comment> +<intertoken space> --> <atmosphere>*} + +@end format + + + + + + +@c This is a kludge, but \multicolumn doesn't work in tabbing environments. + + + +@format +@t{<identifier> --> <initial> <subsequent>* + | <peculiar identifier> +<initial> --> <letter> | <special initial> +<letter> --> a | b | c | ... | z + +<special initial> --> ! | $ | % | & | * | / | : | < | = + | > | ? | ^ | _ | ~ +<subsequent> --> <initial> | <digit> + | <special subsequent> +<digit> --> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 +<special subsequent> --> + | - | .@: | @@ +<peculiar identifier> --> + | - | ... +<syntactic keyword> --> <expression keyword> +@cindex @w{syntactic keyword} +@cindex @w{keyword} + | else | => | define + | unquote | unquote-splicing +<expression keyword> --> quote | lambda | if + | set! | begin | cond | and | or | case + | let | let* | letrec | do | delay + | quasiquote + +@w{@samp{<variable> @result{} <}}@r{any <identifier> that isn't} +@cindex @w{variable} + @w{ @r{also a <syntactic keyword>>}} + +<boolean> --> #t | #f +<character> --> #\ <any character> + | #\ <character name> +<character name> --> space | newline + +<string> --> " <string element>* " +<string element> --> <any character other than " or \> + | \" | \\ } + +@end format + + + + + + + +@format +@t{<number> --> <num 2>| <num 8> + | <num 10>| <num 16> +} + +@end format + + + +The following rules for <num R>, <complex R>, <real +R>, <ureal R>, <uinteger R>, and <prefix R> +should be replicated for @w{R = 2, 8, 10,} +and 16. There are no rules for <decimal 2>, <decimal +8>, and <decimal 16>, which means that numbers containing +decimal points or exponents must be in decimal radix. +@ignore todo +Mark Meyer and David Bartley want to fix this. (What? -- Will) +@end ignore + + + +@format +@t{<num R> --> <prefix R> <complex R> +<complex R> --> <real R> | <real R> @@ <real R> + | <real R> + <ureal R> i | <real R> - <ureal R> i + | <real R> + i | <real R> - i + | + <ureal R> i | - <ureal R> i | + i | - i +<real R> --> <sign> <ureal R> +<ureal R> --> <uinteger R> + | <uinteger R> / <uinteger R> + | <decimal R> +<decimal 10> --> <uinteger 10> <suffix> + | . <digit 10>+ #* <suffix> + | <digit 10>+ . <digit 10>* #* <suffix> + | <digit 10>+ #+ . #* <suffix> +<uinteger R> --> <digit R>+ #* +<prefix R> --> <radix R> <exactness> + | <exactness> <radix R> +} + +@end format + + + + +@format +@t{<suffix> --> <empty> + | <exponent marker> <sign> <digit 10>+ +<exponent marker> --> e | s | f | d | l +<sign> --> <empty> | + | - +<exactness> --> <empty> | #i | #e +@vindex #e +@vindex #i +<radix 2> --> #b +@vindex #b +<radix 8> --> #o +@vindex #o +<radix 10> --> <empty> | #d +<radix 16> --> #x +@vindex #x +<digit 2> --> 0 | 1 +<digit 8> --> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 +<digit 10> --> <digit> +<digit 16> --> <digit 10> | a | b | c | d | e | f } + +@end format + + + +@ignore todo +Mark Meyer of TI sez, shouldn't we allow @t{1e3/2}? +@end ignore + + + +@node External representation, Expression, Lexical structure, Formal syntax +@subsection External representations + + + +<Datum> is what the @code{read} procedure (section @pxref{Input}) +@vindex @w{read} +successfully parses. Note that any string that parses as an +<ex@-pres@-sion> will also parse as a <datum>. + + +@format +@t{<datum> --> <simple datum> | <compound datum> +<simple datum> --> <boolean> | <number> + | <character> | <string> | <symbol> +<symbol> --> <identifier> +<compound datum> --> <list> | <vector> +<list> --> (<datum>*) | (<datum>+ .@: <datum>) + | <abbreviation> +<abbreviation> --> <abbrev prefix> <datum> +<abbrev prefix> --> ' | ` | , | ,@@ +<vector> --> #(<datum>*) } + +@end format + + + + +@node Expression, Quasiquotations, External representation, Formal syntax +@subsection Expressions + + + +@format +@t{<expression> --> <variable> + | <literal> + | <procedure call> + | <lambda expression> + | <conditional> + | <assignment> + | <derived expression> + | <macro use> + | <macro block> + +<literal> --> <quotation> | <self-evaluating> +<self-evaluating> --> <boolean> | <number> + | <character> | <string> +<quotation> --> '<datum> | (quote <datum>) +<procedure call> --> (<operator> <operand>*) +<operator> --> <expression> +<operand> --> <expression> + +<lambda expression> --> (lambda <formals> <body>) +<formals> --> (<variable>*) | <variable> + | (<variable>+ .@: <variable>) +<body> --> <definition>* <sequence> +<sequence> --> <command>* <expression> +<command> --> <expression> + +<conditional> --> (if <test> <consequent> <alternate>) +<test> --> <expression> +<consequent> --> <expression> +<alternate> --> <expression> | <empty> + +<assignment> --> (set! <variable> <expression>) + +<derived expression> --> + (cond <cond clause>+) + | (cond <cond clause>* (else <sequence>)) + | (case <expression> + <case clause>+) + | (case <expression> + <case clause>* + (else <sequence>)) + | (and <test>*) + | (or <test>*) + | (let (<binding spec>*) <body>) + | (let <variable> (<binding spec>*) <body>) + | (let* (<binding spec>*) <body>) + | (letrec (<binding spec>*) <body>) + | (begin <sequence>) + | (do (<iteration spec>*) + (<test> <do result>) + <command>*) + | (delay <expression>) + | <quasiquotation> + +<cond clause> --> (<test> <sequence>) + | (<test>) + | (<test> => <recipient>) +<recipient> --> <expression> +<case clause> --> ((<datum>*) <sequence>) +<binding spec> --> (<variable> <expression>) +<iteration spec> --> (<variable> <init> <step>) + | (<variable> <init>) +<init> --> <expression> +<step> --> <expression> +<do result> --> <sequence> | <empty> + +<macro use> --> (<keyword> <datum>*) +<keyword> --> <identifier> + +<macro block> --> + (let-syntax (<syntax spec>*) <body>) + | (letrec-syntax (<syntax spec>*) <body>) +<syntax spec> --> (<keyword> <transformer spec>) + +} + +@end format + + + +@node Quasiquotations, Transformers, Expression, Formal syntax +@subsection Quasiquotations + + +The following grammar for quasiquote expressions is not context-free. +It is presented as a recipe for generating an infinite number of +production rules. Imagine a copy of the following rules for D = 1, 2,3, @dots{}. D keeps track of the nesting depth. + + +@format +@t{<quasiquotation> --> <quasiquotation 1> +<qq template 0> --> <expression> +<quasiquotation D> --> `<qq template D> + | (quasiquote <qq template D>) +<qq template D> --> <simple datum> + | <list qq template D> + | <vector qq template D> + | <unquotation D> +<list qq template D> --> (<qq template or splice D>*) + | (<qq template or splice D>+ .@: <qq template D>) + | '<qq template D> + | <quasiquotation D+1> +<vector qq template D> --> #(<qq template or splice D>*) +<unquotation D> --> ,<qq template D-1> + | (unquote <qq template D-1>) +<qq template or splice D> --> <qq template D> + | <splicing unquotation D> +<splicing unquotation D> --> ,@@<qq template D-1> + | (unquote-splicing <qq template D-1>) } + +@end format + + + +In <quasiquotation>s, a <list qq template D> can sometimes +be confused with either an <un@-quota@-tion D> or a <splicing +un@-quo@-ta@-tion D>. The interpretation as an +<un@-quo@-ta@-tion> or <splicing +un@-quo@-ta@-tion D> takes precedence. + +@node Transformers, Programs and definitions, Quasiquotations, Formal syntax +@subsection Transformers + + + +@format +@t{<transformer spec> --> + (syntax-rules (<identifier>*) <syntax rule>*) +<syntax rule> --> (<pattern> <template>) +<pattern> --> <pattern identifier> + | (<pattern>*) + | (<pattern>+ . <pattern>) + | (<pattern>* <pattern> <ellipsis>) + | #(<pattern>*) + | #(<pattern>* <pattern> <ellipsis>) + | <pattern datum> +<pattern datum> --> <string> + | <character> + | <boolean> + | <number> +<template> --> <pattern identifier> + | (<template element>*) + | (<template element>+ . <template>) + | #(<template element>*) + | <template datum> +<template element> --> <template> + | <template> <ellipsis> +<template datum> --> <pattern datum> +<pattern identifier> --> <any identifier except @samp{...}> +<ellipsis> --> <the identifier @samp{...}> +} + +@end format + + + +@node Programs and definitions, , Transformers, Formal syntax +@subsection Programs and definitions + + + +@format +@t{<program> --> <command or definition>* +<command or definition> --> <command> + | <definition> + | <syntax definition> + | (begin <command or definition>+) +<definition> --> (define <variable> <expression>) + | (define (<variable> <def formals>) <body>) + | (begin <definition>*) +<def formals> --> <variable>* + | <variable>* .@: <variable> +<syntax definition> --> + (define-syntax <keyword> <transformer spec>) +} + +@end format + + + +@node Formal semantics, Derived expression type, Formal syntax, Formal syntax and semantics +@section Formal semantics + + +This section provides a formal denotational semantics for the primitive +expressions of Scheme and selected built-in procedures. The concepts +and notation used here are described in @sc{[Stoy77]}. + +@quotation +@emph{Note:} The formal semantics section was written in La@TeX{} which +is incompatible with @TeX{}info. See the Formal semantics section of +the original document from which this was derived. +@end quotation + + +@c @include{derive} +@node Derived expression type, , Formal semantics, Formal syntax and semantics +@section Derived expression types + + + +This section gives macro definitions for the derived expression types in +terms of the primitive expression types (literal, variable, call, @samp{lambda}, +@samp{if}, @samp{set!}). See section @ref{Control features} for a possible +definition of @samp{delay}. + + +@example + +(define-syntax cond + (syntax-rules (else =>) + ((cond (else result1 result2 ...)) + (begin result1 result2 ...)) + ((cond (test => result)) + (let ((temp test)) + (if temp (result temp)))) + ((cond (test => result) clause1 clause2 ...) + (let ((temp test)) + (if temp + (result temp) + (cond clause1 clause2 ...)))) + ((cond (test)) test) + ((cond (test) clause1 clause2 ...) + (let ((temp test)) + (if temp + temp + (cond clause1 clause2 ...)))) + ((cond (test result1 result2 ...)) + (if test (begin result1 result2 ...))) + ((cond (test result1 result2 ...) + clause1 clause2 ...) + (if test + (begin result1 result2 ...) + (cond clause1 clause2 ...))))) + +@end example + + + +@example + +(define-syntax case + (syntax-rules (else) + ((case (key ...) + clauses ...) + (let ((atom-key (key ...))) + (case atom-key clauses ...))) + ((case key + (else result1 result2 ...)) + (begin result1 result2 ...)) + ((case key + ((atoms ...) result1 result2 ...)) + (if (memv key '(atoms ...)) + (begin result1 result2 ...))) + ((case key + ((atoms ...) result1 result2 ...) + clause clauses ...) + (if (memv key '(atoms ...)) + (begin result1 result2 ...) + (case key clause clauses ...))))) + +@end example + + + +@example + +(define-syntax and + (syntax-rules () + ((and) #t) + ((and test) test) + ((and test1 test2 ...) + (if test1 (and test2 ...) #f)))) + +@end example + + + +@example + +(define-syntax or + (syntax-rules () + ((or) #f) + ((or test) test) + ((or test1 test2 ...) + (let ((x test1)) + (if x x (or test2 ...)))))) + +@end example + + + +@example + +(define-syntax let + (syntax-rules () + ((let ((name val) ...) body1 body2 ...) + ((lambda (name ...) body1 body2 ...) + val ...)) + ((let tag ((name val) ...) body1 body2 ...) + ((letrec ((tag (lambda (name ...) + body1 body2 ...))) + tag) + val ...)))) + +@end example + + + +@example + +(define-syntax let* + (syntax-rules () + ((let* () body1 body2 ...) + (let () body1 body2 ...)) + ((let* ((name1 val1) (name2 val2) ...) + body1 body2 ...) + (let ((name1 val1)) + (let* ((name2 val2) ...) + body1 body2 ...))))) + +@end example + + +The following @samp{letrec} macro uses the symbol @samp{<undefined>} +in place of an expression which returns something that when stored in +a location makes it an error to try to obtain the value stored in the +location (no such expression is defined in Scheme). +A trick is used to generate the temporary names needed to avoid +specifying the order in which the values are evaluated. +This could also be accomplished by using an auxiliary macro. + + +@example + +(define-syntax letrec + (syntax-rules () + ((letrec ((var1 init1) ...) body ...) + (letrec "generate temp names" + (var1 ...) + () + ((var1 init1) ...) + body ...)) + ((letrec "generate temp names" + () + (temp1 ...) + ((var1 init1) ...) + body ...) + (let ((var1 <undefined>) ...) + (let ((temp1 init1) ...) + (set! var1 temp1) + ... + body ...))) + ((letrec "generate temp names" + (x y ...) + (temp ...) + ((var1 init1) ...) + body ...) + (letrec "generate temp names" + (y ...) + (newtemp temp ...) + ((var1 init1) ...) + body ...)))) + +@end example + + + +@example + +(define-syntax begin + (syntax-rules () + ((begin exp ...) + ((lambda () exp ...))))) + +@end example + + +The following alternative expansion for @samp{begin} does not make use of +the ability to write more than one expression in the body of a lambda +expression. In any case, note that these rules apply only if the body +of the @samp{begin} contains no definitions. + + +@example + +(define-syntax begin + (syntax-rules () + ((begin exp) + exp) + ((begin exp1 exp2 ...) + (let ((x exp1)) + (begin exp2 ...))))) + +@end example + + +The following definition +of @samp{do} uses a trick to expand the variable clauses. +As with @samp{letrec} above, an auxiliary macro would also work. +The expression @samp{(if #f #f)} is used to obtain an unspecific +value. + + +@example + +(define-syntax do + (syntax-rules () + ((do ((var init step ...) ...) + (test expr ...) + command ...) + (letrec + ((loop + (lambda (var ...) + (if test + (begin + (if #f #f) + expr ...) + (begin + command + ... + (loop (do "step" var step ...) + ...)))))) + (loop init ...))) + ((do "step" x) + x) + ((do "step" x y) + y))) + +@end example + + +@c `a = Q_1[a] +@c `(a b c ... . z) = `(a . (b c ...)) +@c `(a . b) = (append Q*_0[a] `b) +@c `(a) = Q*_0[a] +@c Q*_0[a] = (list 'a) +@c Q*_0[,a] = (list a) +@c Q*_0[,@a] = a +@c Q*_0[`a] = (list 'quasiquote Q*_1[a]) +@c `#(a b ...) = (list->vector `(a b ...)) +@c ugh. + +@page + +@c @include{notes} +@node Notes, Additional material, Formal syntax and semantics, top +@unnumbered Notes + +@menu +* Language changes:: +@end menu + + + +@ignore todo +Perhaps this section should be made to disappear. +Can these remarks be moved somewhere else? +@end ignore + + +@node Language changes, , Notes, Notes +@unnumberedsec Language changes + + + +This section enumerates the changes that have been made to Scheme since +the ``Revised^4 report'' [R4RS] was published. + + + +@itemize @bullet + + +@item +The report is now a superset of the IEEE standard for Scheme +[IEEEScheme]: implementations that conform to the report will +also conform to the standard. This required the following changes: + + +@itemize @bullet + + +@item +The empty list is now required to count as true. + +@item +The classification of features as essential or inessential has been +removed. There are now three classes of built-in procedures: primitive, +library, and optional. The optional procedures are @samp{load}, +@samp{with-input-from-file}, @samp{with-output-to-file}, +@samp{transcript-on}, @samp{transcript-off}, and +@samp{interaction-environment}, +and @samp{-} and @samp{/} with more than two arguments. +None of these are in the IEEE standard. + +@item +Programs are allowed to redefine built-in procedures. Doing so +will not change the behavior of other built-in procedures. + +@end itemize + + +@item +@emph{Port} has been added to the list of disjoint types. + +@item +The macro appendix has been removed. High-level macros are now part +of the main body of the report. The rewrite rules for derived expressions +have been replaced with macro definitions. There are no reserved identifiers. + +@item +@samp{Syntax-rules} now allows vector patterns. + +@item +Multiple-value returns, @samp{eval}, and @samp{dynamic-wind} have +been added. + +@item +The calls that are required to be implemented in a properly tail-recursive +fashion are defined explicitly. + +@item +`@samp{@@}' can be used within identifiers. `@samp{|}' is reserved +for possible future extensions. + + +@end itemize + + +@c %R4%% +@c \subsection*{Keywords as variable names} + +@c Some implementations allow arbitrary syntactic +@c keywords \index{keyword}\index{syntactic keyword}to be used as variable +@c names, instead of reserving them, as this report would have +@c it.\index{variable} But this creates ambiguities in the interpretation +@c of expressions: for example, in the following, it's not clear whether +@c the expression {\tt (if 1 2 3)} should be treated as a procedure call or +@c as a conditional. + +@c \begin{scheme} +@c (define if list) +@c (if 1 2 3) \ev 2 {\em{}or} (1 2 3)% +@c \end{scheme} + +@c These ambiguities are usually resolved in some consistent way within any +@c given implementation, but no particular treatment stands out as being +@c clearly superior to any other, so these situations were excluded for the +@c purposes of this report. + +@c %R4%% +@c \subsection*{Macros} + +@c Scheme does not have any standard facility for defining new kinds of +@c expressions.\index{macros} + +@c \vest The ability to alter the syntax of the language creates +@c numerous problems. All current implementations of Scheme have macro +@c facilities that solve those problems to one degree or another, but the +@c solutions are quite different and it isn't clear at this time which +@c solution is best, or indeed whether any of the solutions are truly +@c adequate. Rather than standardize, we are encouraging implementations +@c to continue to experiment with different solutions. + +@c \vest The main problems with traditional macros are: They must be +@c defined to the system before any code using them is loaded; this is a +@c common source of obscure bugs. They are usually global; macros can be +@c made to follow lexical scope rules \todo{flushed: ``as in Common +@c Lisp's {\tt macrolet}''; OK?}, but many people find the resulting scope rules +@c confusing. Unless they are written very carefully, macros are +@c vulnerable to inadvertent capture of free variables; to get around this, +@c for example, macros may have to generate code in which procedure values +@c appear as quoted constants. There is a similar problem with syntactic +@c keywords if the keywords of special forms are not reserved. If keywords +@c are reserved, then either macros introduce new reserved words, +@c invalidating old code, or else special forms defined by the programmer +@c do not have the same status as special forms defined by the system. + +@c \todo{Refer to Pitman's special forms paper.} +@c \todo{Pitman sez: Discuss importance of having a small number of special forms +@c so that programs can inspect each other.} + +@ignore todo +Move cwcc history back here? --- Andy Cromarty is concerned about +confusion over who the audience is. +@end ignore + + +@ignore todo +Cromarty: +23. NOTES, p.35ff.: This material should stay somehow. We need to + make it clear that R^3 Scheme is not being touted as Yet Another + Ultimate Solution To The Programming Language Problem, but rather + as a snapshot of a *process* of good design, for which not all + answers have yet been found. We also ought to use the opportunity + for publicity afforded us by SIGPLAN to advertise some of the thorny + unsolved problems that need further research, and encourage + language designers to work on them. +@end ignore + + +@c @include{repository} +@node Additional material, Example, Notes, top +@unnumbered Additional material + + +The Internet Scheme Repository at + +@center +@center @url{http://www.cs.indiana.edu/scheme-repository/} +@center + +contains an extensive Scheme bibliography, as well as papers, +programs, implementations, and other material related to Scheme. + +@page + +@c @include{example} + +@node Example, Bibliography, Additional material, top +@unnumbered Example + +@c -*- Mode: Lisp; Package: SCHEME; Syntax: Common-lisp -*- + + +@samp{Integrate-system} integrates the system + + +@center y_k^^ = f_k(y_1, y_2, @dots{}, y_n), k = 1, @dots{}, n + +of differential equations with the method of Runge-Kutta. + +The parameter @t{system-derivative} is a function that takes a system +state (a vector of values for the state variables y_1, @dots{}, y_n) +and produces a system derivative (the values y_1^^, @dots{},y_n^^). The parameter @t{initial-state} provides an initial +system state, and @t{h} is an initial guess for the length of the +integration step. + +The value returned by @samp{integrate-system} is an infinite stream of +system states. + + +@example + +(define integrate-system + (lambda (system-derivative initial-state h) + (let ((next (runge-kutta-4 system-derivative h))) + (letrec ((states + (cons initial-state + (delay (map-streams next + states))))) + states)))) + +@end example + + +@samp{Runge-Kutta-4} takes a function, @t{f}, that produces a +system derivative from a system state. @samp{Runge-Kutta-4} +produces a function that takes a system state and +produces a new system state. + + +@example + +(define runge-kutta-4 + (lambda (f h) + (let ((*h (scale-vector h)) + (*2 (scale-vector 2)) + (*1/2 (scale-vector (/ 1 2))) + (*1/6 (scale-vector (/ 1 6)))) + (lambda (y) + ;; y @r{}is a system state + (let* ((k0 (*h (f y))) + (k1 (*h (f (add-vectors y (*1/2 k0))))) + (k2 (*h (f (add-vectors y (*1/2 k1))))) + (k3 (*h (f (add-vectors y k2))))) + (add-vectors y + (*1/6 (add-vectors k0 + (*2 k1) + (*2 k2) + k3)))))))) +@c |--------------------------------------------------| + +(define elementwise + (lambda (f) + (lambda vectors + (generate-vector + (vector-length (car vectors)) + (lambda (i) + (apply f + (map (lambda (v) (vector-ref v i)) + vectors))))))) + +@c |--------------------------------------------------| +(define generate-vector + (lambda (size proc) + (let ((ans (make-vector size))) + (letrec ((loop + (lambda (i) + (cond ((= i size) ans) + (else + (vector-set! ans i (proc i)) + (loop (+ i 1))))))) + (loop 0))))) + +(define add-vectors (elementwise +)) + +(define scale-vector + (lambda (s) + (elementwise (lambda (x) (* x s))))) + +@end example + + +@samp{Map-streams} is analogous to @samp{map}: it applies its first +argument (a procedure) to all the elements of its second argument (a +stream). + + +@example + +(define map-streams + (lambda (f s) + (cons (f (head s)) + (delay (map-streams f (tail s)))))) + +@end example + + +Infinite streams are implemented as pairs whose car holds the first +element of the stream and whose cdr holds a promise to deliver the rest +of the stream. + + +@example + +(define head car) +(define tail + (lambda (stream) (force (cdr stream)))) + +@end example + + +@sp 6 +The following illustrates the use of @samp{integrate-system} in +integrating the system + + +@center C dv_C / dt = -i_L - v_C / R + + + +@center L di_L / dt = v_C + +which models a damped oscillator. + + +@example + +(define damped-oscillator + (lambda (R L C) + (lambda (state) + (let ((Vc (vector-ref state 0)) + (Il (vector-ref state 1))) + (vector (- 0 (+ (/ Vc (* R C)) (/ Il C))) + (/ Vc L)))))) + +(define the-states + (integrate-system + (damped-oscillator 10000 1000 .001) + '#(1 0) + .01)) + +@end example + + +@ignore todo +Show some output? +@end ignore + + +@c (letrec ((loop (lambda (s) +@c (newline) +@c (write (head s)) +@c (loop (tail s))))) +@c (loop the-states)) + +@c #(1 0) +@c #(0.99895054 9.994835e-6) +@c #(0.99780226 1.9978681e-5) +@c #(0.9965554 2.9950552e-5) +@c #(0.9952102 3.990946e-5) +@c #(0.99376684 4.985443e-5) +@c #(0.99222565 5.9784474e-5) +@c #(0.9905868 6.969862e-5) +@c #(0.9888506 7.9595884e-5) +@c #(0.9870173 8.94753e-5) + +@page + +@c \newpage % Put bib on it's own page (it's just one) +@c \twocolumn[\vspace{-.18in}]% Last bib item was on a page by itself. +@c \renewcommand{\bibname}{References} +@c @include{bib} + +@c My reference for proper reference format is: +@c Mary-Claire van Leunen. +@c {\em A Handbook for Scholars.} +@c Knopf, 1978. +@c I think the references list would look better in ``open'' format, +@c i.e. with the three blocks for each entry appearing on separate +@c lines. I used the compressed format for SIGPLAN in the interest of +@c space. In open format, when a block runs over one line, +@c continuation lines should be indented; this could probably be done +@c using some flavor of latex list environment. Maybe the right thing +@c to do in the long run would be to convert to Bibtex, which probably +@c does the right thing, since it was implemented by one of van +@c Leunen's colleagues at DEC SRC. +@c -- Jonathan + +@c I tried to follow Jonathan's format, insofar as I understood it. +@c I tried to order entries lexicographically by authors (with singly +@c authored papers first), then by date. +@c In some cases I replaced a technical report or conference paper +@c by a subsequent journal article, but I think there are several +@c more such replacements that ought to be made. +@c -- Will, 1991. + +@c This is just a personal remark on your question on the RRRS: +@c The language CUCH (Curry-Church) was implemented by 1964 and +@c is a practical version of the lambda-calculus (call-by-name). +@c One reference you may find in Formal Language Description Languages +@c for Computer Programming T.~B.~Steele, 1965 (or so). +@c -- Matthias Felleisen + +@c Rather than try to keep the bibliography up-to-date, which is hopeless +@c given the time between updates, I replaced the bulk of the references +@c with a pointer to the Scheme Repository. Ozan Yigit's bibliography in +@c the repository is a superset of the R4RS one. +@c The bibliography now contains only items referenced within the report. +@c -- Richard, 1996. + +@node Bibliography, Index, Example, top +@unnumbered Bibliography + + +@itemize @bullet +@c 999 + + +@item [SICP] +@pindex SICP +Harold Abelson and Gerald Jay Sussman with Julie Sussman. +@emph{Structure and Interpretation of Computer Programs, second edition.} +MIT Press, Cambridge, 1996. + +@item [Bawden88] +@c new +Alan Bawden and Jonathan Rees. +@pindex Bawden88 +Syntactic closures. +In @emph{Proceedings of the 1988 ACM Symposium on Lisp and + Functional Programming}, pages 86--95. + +@item [howtoprint] +@pindex howtoprint +Robert G. Burger and R. Kent Dybvig. +Printing floating-point numbers quickly and accurately. +In @emph{Proceedings of the ACM SIGPLAN '96 Conference + on Programming Language Design and Implementation}, pages 108--116. + +@item [RRRS] +@pindex RRRS +William Clinger, editor. +The revised revised report on Scheme, or an uncommon Lisp. +MIT Artificial Intelligence Memo 848, August 1985. +Also published as Computer Science Department Technical Report 174, + Indiana University, June 1985. + +@item [howtoread] +@c new +William Clinger. +@pindex howtoread +How to read floating point numbers accurately. +In @emph{Proceedings of the ACM SIGPLAN '90 Conference + on Programming Language Design and Implementation}, pages 92--101. +Proceedings published as @emph{SIGPLAN Notices} 25(6), June 1990. + +@item [R4RS] +@pindex R4RS +William Clinger and Jonathan Rees, editors. +The revised^4 report on the algorithmic language Scheme. +In @emph{ACM Lisp Pointers} 4(3), pages 1--55, 1991. + +@item [macrosthatwork] +@c new +William Clinger and Jonathan Rees. +@pindex macrosthatwork +Macros that work. +In @emph{Proceedings of the 1991 ACM Conference on Principles of + Programming Languages}, pages 155--162. + +@item [propertailrecursion] +@c new +William Clinger. +@pindex propertailrecursion +Proper Tail Recursion and Space Efficiency. +To appear in @emph{Proceedings of the 1998 ACM Conference on Programming + Language Design and Implementation}, June 1998. + +@item [syntacticabstraction] +@pindex syntacticabstraction +R. Kent Dybvig, Robert Hieb, and Carl Bruggeman. +Syntactic abstraction in Scheme. +@emph{Lisp and Symbolic Computation} 5(4):295--326, 1993. + +@item [Scheme311] +@pindex Scheme311 +Carol Fessenden, William Clinger, Daniel P. Friedman, and Christopher Haynes. +Scheme 311 version 4 reference manual. +Indiana University Computer Science Technical Report 137, February 1983. +Superseded by [Scheme84]. + +@item [Scheme84] +@pindex Scheme84 +D. Friedman, C. Haynes, E. Kohlbecker, and M. Wand. +Scheme 84 interim reference manual. +Indiana University Computer Science Technical Report 153, January 1985. + +@item [IEEE] +@pindex IEEE +@emph{IEEE Standard 754-1985. IEEE Standard for Binary Floating-Point +Arithmetic.} IEEE, New York, 1985. + +@item [IEEEScheme] +@pindex IEEEScheme +@emph{IEEE Standard 1178-1990. IEEE Standard for the Scheme + Programming Language.} IEEE, New York, 1991. + +@item [Kohlbecker86] +@pindex Kohlbecker86 +Eugene E. Kohlbecker Jr. +@emph{Syntactic Extensions in the Programming Language Lisp.} +PhD thesis, Indiana University, August 1986. + +@item [hygienic] +@pindex hygienic +Eugene E. Kohlbecker Jr., Daniel P. Friedman, Matthias Felleisen, and Bruce Duba. +Hygienic macro expansion. +In @emph{Proceedings of the 1986 ACM Conference on Lisp + and Functional Programming}, pages 151--161. + +@item [Landin65] +@pindex Landin65 +Peter Landin. +A correspondence between Algol 60 and Church's lambda notation: Part I. +@emph{Communications of the ACM} 8(2):89--101, February 1965. + +@item [MITScheme] +@pindex MITScheme +MIT Department of Electrical Engineering and Computer Science. +Scheme manual, seventh edition. +September 1984. + +@item [Naur63] +@pindex Naur63 +Peter Naur et al. +Revised report on the algorithmic language Algol 60. +@emph{Communications of the ACM} 6(1):1--17, January 1963. + +@item [Penfield81] +@pindex Penfield81 +Paul Penfield, Jr. +Principal values and branch cuts in complex APL. +In @emph{APL '81 Conference Proceedings,} pages 248--256. +ACM SIGAPL, San Francisco, September 1981. +Proceedings published as @emph{APL Quote Quad} 12(1), ACM, September 1981. + +@item [Pitman83] +@pindex Pitman83 +Kent M. Pitman. +The revised MacLisp manual (Saturday evening edition). +MIT Laboratory for Computer Science Technical Report 295, May 1983. + +@item [Rees82] +@pindex Rees82 +Jonathan A. Rees and Norman I. Adams IV. +T: A dialect of Lisp or, lambda: The ultimate software tool. +In @emph{Conference Record of the 1982 ACM Symposium on Lisp and + Functional Programming}, pages 114--122. + +@item [Rees84] +@pindex Rees84 +Jonathan A. Rees, Norman I. Adams IV, and James R. Meehan. +The T manual, fourth edition. +Yale University Computer Science Department, January 1984. + +@item [R3RS] +@pindex R3RS +Jonathan Rees and William Clinger, editors. +The revised^3 report on the algorithmic language Scheme. +In @emph{ACM SIGPLAN Notices} 21(12), pages 37--79, December 1986. + +@item [Reynolds72] +@pindex Reynolds72 +John Reynolds. +Definitional interpreters for higher order programming languages. +In @emph{ACM Conference Proceedings}, pages 717--740. +ACM, +@ignore todo +month? +@end ignore + 1972. + +@item [Scheme78] +@pindex Scheme78 +Guy Lewis Steele Jr. and Gerald Jay Sussman. +The revised report on Scheme, a dialect of Lisp. +MIT Artificial Intelligence Memo 452, January 1978. + +@item [Rabbit] +@pindex Rabbit +Guy Lewis Steele Jr. +Rabbit: a compiler for Scheme. +MIT Artificial Intelligence Laboratory Technical Report 474, May 1978. + +@item [CLtL] +@pindex CLtL +Guy Lewis Steele Jr. +@emph{Common Lisp: The Language, second edition.} +Digital Press, Burlington MA, 1990. + +@item [Scheme75] +@pindex Scheme75 +Gerald Jay Sussman and Guy Lewis Steele Jr. +Scheme: an interpreter for extended lambda calculus. +MIT Artificial Intelligence Memo 349, December 1975. + +@item [Stoy77] +@pindex Stoy77 +Joseph E. Stoy. +@emph{Denotational Semantics: The Scott-Strachey Approach to + Programming Language Theory.} +MIT Press, Cambridge, 1977. + +@item [TImanual85] +@pindex TImanual85 +Texas Instruments, Inc. +TI Scheme Language Reference Manual. +Preliminary version 1.0, November 1985. + +@end itemize + + + + +@page + + +@c Adjustment to avoid having the last index entry on a page by itself. +@c \addtolength{\baselineskip}{-0.1pt} + +@node Index, , Bibliography, top +@unnumbered Alphabetic index of definitions of concepts, keywords, and procedures + + + +The principal entry for each term, procedure, or keyword is listed +first, separated from the other entries by a semicolon. + +@sp 6 + +@unnumberedsec Concepts +@printindex cp +@page +@unnumberedsec Procedures +@printindex fn + +@ifinfo +@unnumberedsec References +@printindex pg +@end ifinfo + + +@contents +@bye diff --git a/doc/ref/.cvsignore b/doc/ref/.cvsignore new file mode 100644 index 000000000..8eaa8267a --- /dev/null +++ b/doc/ref/.cvsignore @@ -0,0 +1,23 @@ +Makefile +Makefile.in +stamp-vti +stamp-vti.1 +*.log +*.dvi +*.aux +*.toc +*.cp +*.fn +*.vr +*.tp +*.ky +*.pg +*.cps +*.fns +*.tps +*.vrs +*.ps +*.info* +*.html +version.texi +version-tutorial.texi diff --git a/doc/ref/ChangeLog-guile-doc-ref b/doc/ref/ChangeLog-guile-doc-ref new file mode 100644 index 000000000..3d2cc4e09 --- /dev/null +++ b/doc/ref/ChangeLog-guile-doc-ref @@ -0,0 +1,890 @@ +2001-03-09 Neil Jerram <neil@ossau.uklinux.net> + + Moving texinfo files from guile-doc/ref into guile-core/doc: + + * env.texi, indices.texi, mbapi.texi, mltext.texi, scripts.texi, + scsh.texi, tcltk.texi, hierarchy.txt, scheme-indices.texi, + slib.texi, deprecated.texi, scheme-binding.texi, appendices.texi, + scheme-intro.texi, goops.texi, extend.texi, gh.texi, intro.texi, + preface.texi, scm.texi, goops-tutorial.texi, hierarchy.eps, + r4rs.texi, r5rs.texi, texinfo.tex, scheme-reading.texi, + data-rep.texi, scheme-utility.texi, posix.texi, + scheme-control.texi, scheme-debug.texi, scheme-evaluation.texi, + scheme-io.texi, scheme-memory.texi, scheme-modules.texi, + scheme-options.texi, scheme-procedures.texi, + scheme-scheduling.texi, scheme-translation.texi, guile.texi, + scheme-data.texi, scheme-ideas.texi, expect.texi: Removed. + +2001-02-28 Gary Houston <ghouston@arglist.com> + + * expect.texi (Expect): add missing eof? argument in example code. + +2001-02-27 Neil Jerram <neil@ossau.uklinux.net> + + * guile.texi, scheme-data.texi, scheme-ideas.texi: Remove the code + that set paragraph indent to zero, then add @noindent to several + places that need not to be indented. + +2001-02-24 Neil Jerram <neil@ossau.uklinux.net> + + * posix.texi (File System, Time), scheme-control.texi + (Exceptions), scheme-data.texi (Complex, Primitive Numerics, + Random, String Fun, Symbols and Variables, Lists, Bit Vectors, + Hooks), scheme-debug.texi (Debugging), scheme-evaluation.texi + (Reader Extensions, Scheme Read, Fly Evaluation, Loading, + Evaluator Options), scheme-io.texi (Reading, Writing, Default + Ports, File Ports), scheme-memory.texi (Garbage Collection, + Guardians, Objects), scheme-modules.texi (The Guile module + system), scheme-options.texi (Install Config), + scheme-procedures.texi (Procedure Properties, Procedures with + Setters), scheme-scheduling.texi (Arbiters, Asyncs), + scheme-translation.texi (Emacs Lisp Support): Automatic docstring + updates. + + * scheme-io.texi (Binary IO): New node. + + * scheme-control.texi (Multiple Values): New node. + +2001-02-23 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-utility.texi (Sorting), scheme-procedures.texi (Procedure + Properties), scheme-memory.texi (Guardians), scheme-io.texi + (Line/Delimited), scheme-data.texi (String Fun, Symbols and + Variables, Vtables), posix.texi (Ports and File Descriptors, File + System, Network Sockets and Communication): Automatic docstring + updates. + +2001-02-15 Neil Jerram <neil@ossau.uklinux.net> + + * data-rep.texi: Preserve, in comments beginning `@c essay', + material from the standalone version of this essay which is very + soon to be retired from its current location at + guile-core/doc/data-rep.texi. + + * data-rep.texi: Incorporate recent changes to smob example + documentation from the standalone version of this essay. + +2001-02-02 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-reading.texi (Further Reading): Add reference to online + version of SICP. + +2001-01-27 Neil Jerram <neil@ossau.uklinux.net> + + Further changes to get everything to build to dvi with the latest + texinfo.tex. + + * texinfo.tex: Replaced by latest version from ftp.gnu.org. + + * r5rs.texi (Binding constructs): Remove @c inside @t{...} at + lines 2207-2209. + (Lexical structure): Remove @c inside @t{...} at line 7517. + + * r4rs.texi (Example): Remove @c inside @t{...} at lines 6557 and + 6569. + +2001-01-26 Neil Jerram <neil@ossau.uklinux.net> + + * scm.texi (Handling Errors): Improved markup. + (snarfing): Deleted. + + * data-rep.texi: File copied here from sources directory and + integrated into the reference manual structure. + + * extend.texi (Libguile Intro): New file, new node, to introduce + new Part. + + * guile.texi: Merged Parts V and VI into a single Part: "Extending + Applications Using Guile". Improved some top level node names and + descriptions. Include extend.texi and data-rep.texi. + + * preface.texi (Manual Layout): Updated according to merge of + Parts V and VI. + + * gh.texi: Restructured into a single chapter. + + * scm.texi (C Port Interface, Port Implementation): Moved here + from scheme-io.texi. + + * scheme-io.texi (Default Ports): Renamed from `Port + Environment'. + (Port Internals): Contents moved to scm.texi. + + * r5rs.texi: Changes to allow building of r5rs.dvi from r5rs.texi. + Aubrey Jaffer's view - which I agree with - is that, given that + people have the option of building r5rs.dvi from the original + LaTeX distribution for R5RS, it is not worth fixing his master + copy of r5rs.texi and the tool which autogenerates it. On the + other hand, it is a marginal convenience for people to be able to + build hardcopy from r5rs.texi, even if the results are less good + than with the original LaTeX. Hence the following fixes. + (lines 714, 725, 728, 1614, 2258): Remove invalid parentheses from + @deffn statements. + (line 2316): Change @deffnx to @deffn, and insert `@end deffn' to + terminate preceding @deffn. + (line 7320): Insert `@c ' at beginning of lines that are intended + to be @ignore'd. + + * guile.texi, r4rs.texi, r5rs.texi: Align @direntry descriptions + to start in column 32. + +2001-01-24 Neil Jerram <neil@ossau.uklinux.net> + + * intro.texi: Licensing and Layout material moved to + preface.texi. + (Whirlwind Tour): New chapter as top level for preexisting + sections. + + * guile.texi: Various minor changes to improve the structure at + the beginning of the reference manual. + + * preface.texi: New file, to split out "prefatory material". + Initially with Licensing and Layout material taken from + intro.texi. + + * Makefile.am (dist_texis): Add preface.texi. + +2001-01-19 Neil Jerram <neil@ossau.uklinux.net> + + * intro.texi: Change R4RS everywhere to R5RS. + (What is Guile?): Change "compiling" to "translating". + +2001-01-07 Neil Jerram <neil@ossau.uklinux.net> + + * appendices.texi (Internals): Content merged into Symbols and + Variables node of scheme-data.texi. + (Reporting Bugs): Moved to manual Part I. + + * guile.texi: Inserted new Part for `Guile Modules' as distinct + from core Guile Scheme language/features. Other parts renumbered + correspondingly. Module chapters moved into new part. + + * intro.texi (Reporting Bugs): Node moved here from + appendices.texi. + + * posix.texi (POSIX): Node name changed from `POSIX System Calls + and Networking'. + + * scheme-data.texi (Symbols and Variables): Added texinfo markup + to docstrings that didn't have it. Expanded snarfed argument + names like `o' and `s' to `obarray' and `string'. + + * scheme-debug.texi (Debugging): Node name changed from `Internal + Debugging Interface'. + + * scheme-evaluation.texi (Fly Evaluation): Moved doc for + `interaction-environment' here (previously under module doc). + + * scheme-memory.texi: Structure reorganization. + + * scheme-modules.texi: Structure reorganization. Removed empty + subsections `First-class Variables' and `First-class Modules'. + + * scheme-options.texi (Options and Config): Node name changed from + `Options'. + (Install Config) Node name changed from `Configuration Data'. + + * scheme-scheduling.texi (Scheduling): Node name changed from + `Threads and Dynamic Roots'. + + * scheme-translation.texi (Translation): New top level node for + translation documentation. + +2001-01-05 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-exceptions.texi: Removed. + + * Makefile.am (dist_texis): Removed scheme-exceptions.texi. + + * guile.texi (Top): Renamed/redescribed some top level nodes. No + longer include scheme-exceptions.texi. + + * scheme-control.texi: Merge material that was previously in + scheme-exceptions.texi. + + * posix.texi: Updated close-port reference. + + * scheme-binding.texi, scheme-control.texi, + scheme-evaluation.texi, scheme-intro.texi, scheme-io.texi, + scheme-procedures.texi, scheme-utility.texi: Massaged into desired + structure. + + * scheme-data.texi (Generic Data Types): Changed to "Data Types". + (Numbers) Introduction streamlined. + (Complex Numbers) New material. + +2001-01-05 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-data.texi, scheme-io.texi, scheme-memory.texi, + scheme-options.texi: Where a single docstring documents more than + one primitive, add a docstring comment for each additionally + documented primitive. + + * scheme-modules.texi: Update docstring for dynamic-func. + + * scheme-data.texi (Numbers, Numerical Tower, Integers, Reals and + Rationals, Number Syntax): New material. + + * deprecated.texi (Deprecated): Remove obsolete MD5 comment line. + +2000-12-12 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-data.texi (Numbers): Documentation added for scientific + functions. + + * Makefile.am (dist_texis): Updated following split of scheme.texi + into per-chapter files. + +2000-12-07 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-data.texi (Booleans): Written. + (Numbers): Introduction written, primitives organized into + subsections. + +2000-12-06 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-data.texi (Generic Data Types): Added chapter + introduction. + (Bitwise Operations, Random): Moved underneath Numbers. + (Other Data Types): New placeholder section for data types that + are documented elsewhere. + + * scheme-indices.texi, scheme-reading.texi: Added Local Variables + block. + +2000-12-06 Neil Jerram <neil@ossau.uklinux.net> + + This change replaces scheme.texi, which is unmanageably large, by + a set of smaller one-per-chapter files. The set and ordering of + the new files reflects the intended top level structure of the + Guile Scheme part of the reference manual. This structure is not + yet all reflected in the combined Texinfo/Info, though, because I + haven't yet fixed the @node levels appropriately. + + * scheme.texi: Removed, after dividing content into new files. + + * scheme-procedures.texi, scheme-utility.texi, + scheme-binding.texi, scheme-control.texi, scheme-io.texi, + scheme-evaluation.texi, scheme-exceptions.texi, + scheme-memory.texi, scheme-modules.texi, scheme-scheduling.texi, + scheme-options.texi, scheme-translation.texi, scheme-debug.texi, + slib.texi: New files. + + * guile.texi: @include new files instead of scheme.texi. Reorder + existing top level nodes. + +2000-12-01 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-data.texi: Remove @page breaks (following demotion). + + * guile.texi (Top), scheme-ideas.texi: Demote everything one level + so that previous chapters About Data, About Procedures, About + Expressions and About Closure are now combined into a single + Scheme Ideas chapter. Add overall chapter introduction. Fix up + top level nodes accordingly. + + * guile.texi (Top), scheme.texi, scheme-data.texi: Gather material + for Generic Data Types chapter into a new file + (scheme-data.texi). @include new file in guile.texi. Fix up top + level nodes accordingly. (This changes demotes all the affected + material by one level, except for that which was already grouped + together under the Data Structures node.) + + * guile.texi (Top): @include new files. + + * scheme-intro.texi, scheme-ideas.texi: New files. + + * scheme.texi (Guile and R5RS Scheme): Moved introductory chapter + to its own file (scheme-intro.texi). + (About Closure) Chapter completed. + (About Data, About Procedures, About Expressions, About Closure): + Ideas chapters moved to their own file (scheme-ideas.texi); + scheme.texi was just getting too large! + +2000-11-09 Gary Houston <ghouston@arglist.com> + + * posix.texi (Ports and File Descriptors): updated + close-all-ports-except. + +2000-11-07 Gary Houston <ghouston@arglist.com> + + * posix.texi (Ports and File Descriptors): added dup2, close-fdes + and port-for-each. + (Pipes): synchronise open-input-pipe, open-output-pipe with + popen.scm. + +2000-11-04 Gary Houston <ghouston@arglist.com> + + * scheme.texi (Generic Port Operations): "port?" added. + +2000-11-03 Neil Jerram <neil@ossau.uklinux.net> + + * scheme.texi (About Expressions): New material about evaluation + and program execution. + + * scheme.texi (About Procedures): Minor textual improvements. + +2000-10-29 Neil Jerram <neil@ossau.uklinux.net> + + * scheme.texi (About Expressions, About Closure): Placeholder + structure for remaining introductory Scheme material. + + * guile.texi (Top): Shorten some menu item lines to fit on a + single console line. + +2000-10-28 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-indices.texi (R5RS Index, Guile Extensions Index): Print + new indices. + + * guile.texi: Define new R5RS and Guile extension indices. + +2000-10-27 Neil Jerram <neil@ossau.uklinux.net> + + * scheme.texi (Guile and R5RS Scheme): Filled in examples of Guile + extensions. + (About Procedures): New introductory material. + + * scheme-reading.texi: New file. + + * scheme-indices.texi: New file. + + * intro.texi (Scripting Examples): Added @* to fix TeX overfull + hboxes (twice). + (end of file): Added Local Variables block for TeX-master + variable. + + * scheme.texi (R4RS Scheme): Node changed to "Guile and R5RS + Scheme". Content changed to indicate that we plan to document + both standard Scheme and Guile extensions. + (About Data, About Procedures, About Expressions): New Scheme + introductory material chapters. + (Options): Moved material on Options into its own chapter. + (Coding With Keywords): New subsection; extends material on use of + keywords to include examples of and references to (ice-9 optargs). + (passim): Change many uses of @example to @lisp, since the + formatting seems to come out better in TeX. + (Optional Arguments): New placeholder chapter (empty). + (end of file): Added Local Variables block for TeX-master + variable. + + * guile.texi (Top): "R4RS Scheme" node changed to "Guile and R5RS + Scheme". Added Scheme introductory chapters: About Data, About + Procedures and About Expressions. New Options chapter for options + material. New Optional Arguments chapter as placeholder for + (ice-9 optargs) material. New chapter for "Further Reading". New + chapters for indices showing what is standard Scheme and what is + Guile extension. + +2000-10-25 Mikael Djurfeldt <mdj@linnaeus.mit.edu> + + * Makefile.am: Added goops.texi and new files to dist_texis. + + * goops.texi, goops-tutorial.texi, hierarchy.eps, hierarchy.txt: + New files. + +2000-10-15 Neil Jerram <neil@ossau.uklinux.net> + + * gh.texi (Starting and controlling the interpreter): Removed + obsolete note about boot-9.scm not being loaded by gh_enter. + (Thanks to Chris Cramer for pointing this out.) + +2000-10-06 Neil Jerram <neil@ossau.uklinux.net> + + * guile.texi, scheme.texi, posix.texi: Simplified docstring + comments: (i) they new refer to the Texinfo-format file that is + generated by snarfing when libguile is built, rather than to + individual C files in the libguile source; (ii) there is no longer + a need to keep MD5 digest values for the corresponding source + docstring, since I'm now using a different mechanism for keeping + track of source material changes. + + * scheme.texi (Lists): Use "@example" in docstring for append. + + * guile.texi, scheme.texi (Primitive Properties): New chapter, + documenting new primitive property primitives. + +2000-09-22 Neil Jerram <neil@ossau.uklinux.net> + + * scm.texi (I/O internals): Add full stops (periods) after + standalone uses of @xref. + + * scheme.texi (Structure Layout): Doc for make-struct-layout + changed to remove reference to "read-only" strings, which no + longer exist. + (Structure Basics): Use @pxref rather than @xref for parenthetical + reference. + (Dynamic Roots): Use @code rather than @var for code, in doc for + call-with-dynamic-root. + (Low level thread primitives): Ditto call-with-new-thread. + (Higher level thread procedures): Ditto call-with-new-thread. + (Symbols and Variables): Docs for gensym and symbol-hash updated + according to libguile changes. + + * posix.texi (Generic Port Operations): Synchronized docstring + for unread-string. + + * gh.texi (Defining new Scheme procedures in C): Avoid texinfo + warning by using @code rather than @var for code. + + * scheme.texi: Lots more docstring comments added, and docs + synchronized with libguile source. + (interaction-environment, make-struct, make-vtable-vtable): Newer, + better doc taken from source file. + (cons-source): New docstring written. + (Vectors): New section added. + (Random, Symbols and Variables): New chapters. + + * posix.texi: Lots more docstring comments added. + (pipe, tzset) Newer, better documentation taken from source file. + + * deprecated.texi: New file, for documenting features that are + deprecated and so planned to disappear. + + * guile.texi (Procedures, Reading and Writing, Random, Sorting, + Symbols and Variables, Deprecated): New chapters in the Scheme + part of the reference manual, to hold docstrings that don't + currently fit anywhere else. + +2000-08-28 Neil Jerram <neil@ossau.uklinux.net> + + * posix.texi (Pipes): open-pipe and close-pipe are procedures (in + ice-9/popen.scm), not primitives. + + * scheme.texi (Generic Port Operations): Remove doc for + port-revealed and set-port-revealed!, since these are covered in + posix.texi. + + * posix.texi: Inserted docstring synchronization comments and + synchronized docstrings for all primitives defined in posix.c, + simpos.c, scmsigs.c, stime.c. + (Ports and File Descriptors) Similarly synchronized port-revealed + and set-port-revealed!. + +2000-08-25 Neil Jerram <neil@ossau.uklinux.net> + + * scheme.texi: Lots more docstrings added. + + * guile.texi (Top): More new chapters: Pairs, Objects, Guardians, + Emacs Lisp Support. + + * scheme.texi (Numbers): New chapter containing docs (many still + empty right now) for numerical primitives. + + * guile.texi (Top): Add chapter for numerical primitives. + +2000-08-18 Neil Jerram <neil@ossau.uklinux.net> + + * posix.texi (Ports and File Descriptors): Docstring for select + substantially changed by update from libguile source. + + * scheme.texi, posix.texi: Lots more primitive docstrings added. + + * guile.texi (Top): Removed empty Reflection chapter, added new + Hooks chapter. + + * scheme.texi: Added docstrings for all Guile primitives from + libguile files from arbiters.c to error.c. + (Reflection): Empty chapter removed. + + * guile.texi (Top): New chapters "Booleans" and "Equality" + (temporary - until we improve the overall organization). + + * scheme.texi (Uniform Arrays): Fix "indentical" typo. + +2000-08-12 Neil Jerram <neil@ossau.uklinux.net> + + * scheme.texi: Removed superfluous "@c docstring end" markers - + docstring.el now uses "@end deffn" to find the end of the + docstring. + Added a lot more docstring comments, and synced up docstrings with + libguile - all libguile primitives documented in scheme.texi now + have docstring comments and are up to date. + (Evaluation): Updated docstring for eval and eval-string (now + R5RS-compliant). + + * intro.texi (Guile Scripts): Added a couple of blank lines. + +2000-08-11 Neil Jerram <neil@ossau.uklinux.net> + + * scheme.texi: Add docstring comments and sync up existing + docstrings with libguile source - complete as far as Association + Lists. + (Keywords): Fill out and improve documentation about + keywords. + + * guile.texi: Set paragraph indent to zero. + +2000-08-07 Neil Jerram <neil@ossau.uklinux.net> + + * scm.texi (libguile error handling): Add note (text supplied by + Gary Houston) giving a pointer on how to do C exception handling + since scm_error_callback was removed. + +2000-08-01 Dirk Herrmann <D.Herrmann@tu-bs.de> + + * scm.texi (libguile error handling): Removed reference to + scm_error_callback, which is not available any more since + guile-1.3. Thanks to Juli-Manel Merino Vidal and to Gary Houston + for pointing this out. + +2000-07-31 Neil Jerram <neil@ossau.uklinux.net> + + * scm.texi (Relationship between Scheme and C functions): + Expand. (Contributed by Thien-Thi Nguyen <ttn@gnu.org>.) + +2000-07-30 Neil Jerram <neil@ossau.uklinux.net> + + * scheme.texi (Association Lists): New, more complete + documentation. + * guile.texi: New top-level manual file based on guile-ref.texi + but modified to reflect the better organization suggested in + sources/jimb-org.texi. + * expect.texi: New file to separate out Expect doc. + * indices.texi: New file to separate indices from appendices. + * intro.texi: Invoking Guile and Meta Switch nodes moved to Guile + Scripting part (scripts.texi). Manual layout node moved to end of + introduction. + * posix.texi: All nodes downgraded one level. Expect, SCSH and + Tcl/Tk nodes moved to dedicated files. + * scheme.texi: Stuff moved around in accordance with + sources/jimb-org.texi reorganization (cvs diff totally confused, + I'm afraid). + * scsh.texi: New file to separate out SCSH doc. + * scripts.texi: New file to separate out Guile scripting doc. + * tcltk.texi: New file to separate out Tcl/Tk interface doc. + * Makefile.am: Changed guile-ref to guile; more distribution + texis. + * Makefile.in: Changed guile-ref to guile; more distribution + texis. + + +2000-05-14 Marius Vollmer <mvo@zagadka.ping.de> + + * posix.texi (Conventions): Added example on how to retrieve errno + value from a system-exception. Thanks to Eric Hanchrow! + +2000-05-04 Marius Vollmer <mvo@zagadka.ping.de> + + * intro.texi: Added chapter about Guile's license. + * guile-ref.texi: Updated menu. + +1999-12-15 Gary Houston <ghouston@freewire.co.uk> + + * scheme.texi (SLIB installation): new node. + +1999-12-06 Gary Houston <ghouston@freewire.co.uk> + + * r4rs.texi: tweaked the dircategory/direntry for compatibility + with the r5 version. + guile-ref.texi: tweaked the dircategory. + * Makefile.am (info_TEXINFOS): add r5rs.texi. + * r5rs.texi: new file, lifted from Aubrey Jaffer's site. + +1999-12-04 Gary Houston <ghouston@freewire.co.uk> + + * scheme.texi (Generic Port Operations): add "port-closed?". + +1999-11-22 Jim Blandy <jimb@savonarola.red-bean.com> + + * mbapi.texi: Don't promise any behavior on ill-formed text. + +1999-11-19 Gary Houston <ghouston@freewire.co.uk> + + * scheme.texi: rewrote the intros in the array nodes. + +1999-11-18 Gary Houston <ghouston@freewire.co.uk> + + * posix.texi (Network Sockets and Communication): add htons etc. + (Ports and File Descriptors, Network Sockets and Communication): + suggest setvbuf instead of duplicate-port for converting + unbuffered ports to buffered. + + * scheme.texi (Uniform Array): add missing array types to the + table. + +1999-11-17 Gary Houston <ghouston@freewire.co.uk> + + * posix.texi (Network Databases): updated. + +1999-10-24 Gary Houston <ghouston@freewire.co.uk> + + * scheme.texi (String Ports): add with-output-to-string and + with-input-from-string. + (Port Implementation): update for ptob seek. + +1999-10-18 Gary Houston <ghouston@freewire.co.uk> + + * scheme.texi (C Port Interface): update the description of + the rw_random port flag. + +1999-09-22 Gary Houston <ghouston@freewire.co.uk> + + * scheme.texi: added a bit of documentation for port internals. + +1999-09-12 Gary Houston <ghouston@easynet.co.uk> + + * posix.texi (File System): make that "directory-stream?". + +1999-09-11 Gary Houston <ghouston@easynet.co.uk> + + * posix.texi (File System): added "directory?". + +1999-09-06 James Blandy <jimb@mule.m17n.org> + + * mbapi.texi, mltext.texi: New files, describing interfaces for + dealing with multilingual code. + +1999-07-25 Gary Houston <ghouston@easynet.co.uk> + + * scheme.texi, posix.texi: updated for changes in the I/O system + and expect macros. + +1999-01-25 Mark Galassi <rosalia@cygnus.com> + + * scheme.texi (General option interface): applied a typo fix. + Thanks to Eric Hanchrow (offby1@blarg.net). + +1998-11-01 Mark Galassi <rosalia@cygnus.com> + + * scheme.texi (Weak References): incorporated David Lutterkort's + chapter on Weak References, which is based on Mikael's email + message exchange with with Michael Livshin. + +1998-10-29 Jim Blandy <jimb@zwingli.cygnus.com> + + * scheme.texi: Corrected shell commands in example. (Thanks to + Chris Bitmead.) + +1998-10-25 Mikael Djurfeldt <mdj@barbara.nada.kth.se> + + * gh.texi (C to Scheme, Scheme to C): Completed entries about + vector conversions. + +1998-08-26 Mark Galassi <rosalia@cygnus.com> + + * gh.texi (Starting and controlling the interpreter): modified the + gh_enter() docs in response to some good comments from Dirk + Herrmann: now they address the issue of loading ice-9/boot-9.scm, + and include Dirk's hackaround for the problem until we fix it + properly. + +1998-04-29 Mark Galassi <rosalia@cygnus.com> + + * scheme.texi (Dynamic Linking from Marius): added Marius's new + chapter on dynamic linking; there is still a section in dynamic + linking (written by Tim maybe?), and I have to examine how to + resolve that. + +1998-03-30 Mikael Djurfeldt <mdj@nada.kth.se> + + * scheme.texi (Port Operations): Changed entry for port-column and + port-line. (Thanks to Per Bothner.) + +1998-02-02 Mikael Djurfeldt <mdj@mdj.nada.kth.se> + + * scheme.texi (Exceptions): Adjusted documentation to reflect the + removal of the (catch #f ...) mechanism. + +1998-01-28 Mark Galassi <rosalia@nis.lanl.gov> + + * guile-ref.texi: changed @dircategory to "Scheme Programming". + It seems to be the consensus. + +1998-01-20 Mikael Djurfeldt <mdj@mdj.nada.kth.se> + + * gh.texi (C to Scheme): Added documentation for gh_doubles2scm + and gh_doubles2dvect. + (Scheme to C): Added documentation for gh_scm2doubles. + +1998-01-15 Mark Galassi <rosalia@nis.lanl.gov> + + * gh.texi (Calling Scheme procedures from C): removed + gh_make_subr() since Mikael pointed out that it is gone from + Guile. I don't remember its history any more, but I don't think + anyone is missing it. + +1998-01-03 Tim Pierce <twp@skepsis.com> + + * scheme.texi (Evaluation): Several corrections supplied by MDJ. + +Sat Dec 27 19:02:36 1997 Tim Pierce <twp@skepsis.com> + + * appendices.texi (Internals, Symbols): New nodes. + * scheme.texi (Configuration Data): New node. + +1997-12-27 Tim Pierce <twp@skepsis.com> + + * guile-ref.texi (Bitwise Operations): New description. + +1997-12-24 Tim Pierce <twp@skepsis.com> + + * scheme.texi (Port Operations, Evaluation): New nodes. + +1997-12-13 Tim Pierce <twp@skepsis.com> + + * scheme.texi, posix.texi: Documented each procedure as `procedure', + `primitive' or `syntax' as appropriate. + (Records): Change record-type-field-names to record-type-fields. + (Low level thread primitives): Change with-new-thread to + call-with-new-thread. + +Sun Dec 7 22:47:22 1997 Gary Houston <ghouston@actrix.gen.nz> + + * posix.texi (Processes): add "system" procedure. + +1997-11-23 Mark Galassi <rosalia@cygnus.com> + + * gh.texi (Starting and controlling the interpreter): added + documentation for gh_repl() -- gh_repl() has changed since I saw + the scm_shell() routine. + +1997-11-19 Tim Pierce <twp@twp.tezcat.com> + + * scheme.texi (String Fun): New node. + (Hash Tables): Added `get-handle' and `create-handle!' docs. + + * posix.texi (Networking Databases): Add docs for gethost, getnet, + getserv, getproto. Expanded on miscellaneous docs. + +1997-11-18 Tim Pierce <twp@twp.tezcat.com> + + * posix.texi: New file; moved docs for POSIX interface here. + * Makefile.am: Add posix.texi. + * Makefile.in: Regenerated. + * guile-ref.texi: Reorganize top-level menu. @include posix.texi. + * scheme.texi: Moved many nodes around, some restructuring + (e.g. new "Data Structures" node for records, structures, arrays, + hash tables, and so on). + +1997-10-19 Mark Galassi <rosalia@cygnus.com> + + * gh.texi (Calling Scheme procedures from C): added many routines + as I go through R4RS and try to complete the gh_ interface. + +Wed Oct 8 04:51:54 1997 Gary Houston <ghouston@actrix.gen.nz> + + * scheme.texi (Dynamic Roots): added batch mode procedures. + +1997-10-03 Mikael Djurfeldt <mdj@nada.kth.se> + + * scheme.texi (Vtables): Changed 0 --> @code{vtable-index-layout}; + Changed @code{struct-vtable-offset} --> @code{vtable-offset-user}; + Added short note about the print call-back initializer. (This + section is in need of review. However, we shoudn't spend much + time on it since the structs will be replaced by something + equivalent, but with a different interface.} + +Sun Sep 28 00:02:35 1997 Mark Galassi <rosalia@nis.lanl.gov> + + * scheme.texi (Keywords): very small re-organization to take + advantage of the fact that read-options is now documented in + another chapter. + +Thu Sep 25 23:37:02 1997 Mark Galassi <rosalia@nis.lanl.gov> + + * scheme.texi (Guile options interface): renamed the symbol case + section to "Guile options interface". "Reader options" is now a + subsection of that. I've finally figured a lot of how options + work, thanks to discovering Mikael's comments in options.c and an + old note from Mikael to Jim describing it. + (Guile options interface): reorganized the individual option + groups. This section (on options) of the manual is now reasonably + complete, unless I am completely missing something. + +Wed Sep 24 15:25:03 1997 Mark Galassi <rosalia@nis.lanl.gov> + + * scheme.texi (The Guile module system): Added a bit more to this + chapter, mostly the more user-friendly (use-modules (ice-9 + module-name)) approach. + (Symbol case): tried to write something about this, but it will + need to be reviewed by someone who understands the big picture of + read options. I also think the section name should be changed to + something like "Read options". + +Sun Sep 21 18:45:57 1997 Mark Galassi <rosalia@nis.lanl.gov> + + * scheme.texi (SLIB): some little details, including splitting off + what does in the installation chapter. Also added a section on + Jacal, which has some open issues. + + * appendices.texi (Packages not shipped with Guile): added this + section to describe getting resources on SCSH, SLIB and Jacal (and + who knows what else in the future). + +Sat Aug 30 19:31:22 1997 Gary Houston <ghouston@actrix.gen.nz> + + * scheme.texi (Uniform Array): mention start and end arguments + for uniform-array-read! and uniform-array-write. + +Sat Aug 23 19:05:08 1997 Gary Houston <ghouston@actrix.gen.nz> + + * guile-ref.texi (Top): corresponding changes. + * scheme.texi (Exception Handling): add scm-error, strerror. + (Exceptions): renamed from Exception Handling. + (Exceptions): deleted empty section. + +Mon Aug 18 16:11:43 1997 Jim Blandy <jimb@totoro.red-bean.com> + + * texinfo.tex: Installed from texinfo release 3.11. + +Fri Aug 15 08:14:32 1997 Gary Houston <ghouston@actrix.gen.nz> + + * scheme.texi (file system): added truncate-file. + chown, fcntl, fseek, ftell updated. + (ports vs file descriptors): added fsync, open, open-fdes. + (time): added times. + +Sun Aug 10 07:39:55 1997 Gary Houston <ghouston@actrix.gen.nz> + + * scheme.texi (processes): added execle. + +Tue Jul 29 02:01:21 1997 Gary Houston <ghouston@actrix.gen.nz> + + * setvbuf added. primitive-dup[2] removed. + +Sat Jul 26 04:25:40 1997 Gary Houston <ghouston@actrix.gen.nz> + + * various close and dup procedures added, plus setenv. + +Sat Jul 19 04:04:50 1997 Gary Houston <ghouston@actrix.gen.nz> + + * scheme.texi (signals): new section. + (processes): primitive-exit. + (ports vs. file descriptors): force-output, flush-all-ports. + fcntl from NEWS. + +Fri Jul 18 07:58:52 1997 Gary Houston <ghouston@actrix.gen.nz> + + * scheme.texi (SLIB): update initialization details. + (expect): likewise. + (The Scheme shell (scsh)): likewise. + +Fri Jun 27 00:31:25 1997 Tim Pierce <twp@twp.tezcat.com> + + * scheme.texi (Regexp Functions): Add docs for make-regexp flags + regexp/icase, regexp/newline, regexp/basic, regexp/extended. + +Mon Jun 23 12:35:57 1997 Tim Pierce <twpierce@bio-5.bsd.uchicago.edu> + + * appendices.texi (debugger user interface): new text. + (Single-Step, Trace, Backtrace): new nodes. + + * scheme.texi: Many revised nodes, some new ones. + + (Binary Numeric Operations, Input/Output Ports, File Ports, Soft + Ports, String Ports): Imported documentation from SCM and SLIB manuals. + + (Association Lists and Hash Tables, Dictionary Types, Association + Lists, Hash Tables): New nodes. + (Dictionaries in general): Removed. + + (Regular Expressions): Replaced. + (Rx Interface): New node, renamed from old `Regular Expressions'. + (Regexp Functions, Match Functions, Backslash Escapes): new nodes. + + (Property Lists): new node with documentation for both object and + procedure properties. + (Object Properties): removed. + * guile-ref.texi: change `Object Properties' to `Property Lists'. + diff --git a/doc/ref/api.txt b/doc/ref/api.txt new file mode 100644 index 000000000..367cbbf95 --- /dev/null +++ b/doc/ref/api.txt @@ -0,0 +1,185 @@ +Scheme objects +============== + +There are two basic C data types to represent objects in guile: + +- SCM: 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 SCM. +Only use macros and functions to work with SCM values. Values are converted +between C data types and the SCM type with utility functions and macros. + +- scm_bits_t: An 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 used to implement guile internals, the use of this type is +also necessary to write certain kinds of extensions to guile. + + +Relationship between SCM and scm_bits_t +======================================= + +A variable of type SCM is guaranteed to hold a valid scheme object. A +variable of type scm_bits_t, however, may either hold a representation of a +SCM value as a C integral type, but may also hold any C value, even if it does +not correspond to a valid scheme object. + +For a variable x of type SCM, the scheme object's type information is stored +in a form that is not directly usable. To be able to work on the type +encoding of the scheme value, the SCM variable has to be transformed into the +corresponding representation as a scm_bits_t variable y by using the +SCM_UNPACK macro. After this has been done, the type of the scheme object x +can be derived from the content of the bits of the scm_bits_t value y, as is +described in -->data-rep. A valid bit encoding of a scheme value as a +scm_bits_t variable can be transformed into the corresponding SCM value by +using the SCM_PACK macro. + +- scm_bits_t SCM_UNPACK (SCM x): Transforms the SCM value x into it's +representation as an integral type. Only after applying SCM_UNPACK it is +possible to access the bits and contents of the SCM value. + +- SCM SCM_PACK (scm_bits_t x): Takes a valid integral representation of a +scheme object and transforms it into its representation as a SCM value. + + +Immediate objects +================= + +A scheme object may either be an immediate, i. e. carrying all necessary +information by itself, or it may contain a reference to a 'cell' with +additional information on the heap. While the fact, whether an object is an +immediate or not should be irrelevant for user code, within guile's own code +the distinction is sometimes of importance. Thus, the following low level +macro is provided: + +- int SCM_IMP (SCM x): A scheme object is an immediate if it fullfills the +SCM_IMP predicate, otherwise it holds an encoded reference to a heap cell. +The result of the predicate is delivered as a C style boolean value. User +code and code that extends guile should normally not be required to use this +macro. + +Summary: +* For a scheme object x of unknown type, check first with SCM_IMP (x) if it is +an immediate object. If so, all of the type and value information can be +determined from the scm_bits_t value that is delivered by SCM_UNPACK (x). + + +Non immediate objects +===================== + +- (scm_cell *) SCM2PTR (SCM x) (FIXME:: this name should be changed) +- SCM PTR2SCM (scm_cell * x) (FIXME:: this name should be changed) + +A scheme object of type SCM that does not fullfill the SCM_IMP predicate holds +an encoded reference to a heap cell. This reference can be decoded to a C +pointer to a heap cell using the SCM2PTR macro. The encoding of a pointer to +a heap cell into a SCM value is done using the PTR2SCM macro. + +Note that it is also possible to transform a non immediate SCM value by using +SCM_UNPACK into a scm_bits_t variable. Hower, the result of SCM_UNPACK may +not be used as a pointer to a scm_cell: Only SCM2PTR is guaranteed to +transform a SCM object into a valid pointer to a heap cell. Also, it is not +allowed to apply PTR2SCM to anything that is not a valid pointer to a heap +cell. + +Summary: +* Only use SCM2PTR for SCM values for which SCM_IMP is false! +* Don't use '(scm_cell*) SCM_UNPACK (x)'! Use 'SCM2PTR (x)' instead! +* Don't use PTR2SCM for anything but a cell pointer! + + +Heap Cell Type Information +========================== + +Heap cells contain a number of entries, each of which is either a scheme +object of type SCM or a raw C value of type scm_bits_t. Which of the cell +entries contain scheme objects and which contain raw C values is determined by +the first entry of the cell, which holds the cell type information. + +- scm_bits_t SCM_CELL_TYPE (SCM x): For a non immediate scheme object x, +deliver the content of the first entry of the heap cell referenced by x. This +value holds the information about the cell type as described in -->data-rep. + +- void SCM_SET_CELL_TYPE (SCM x, scm_bits_t t): For a non immediate scheme +object x, write the value t into the first entry of the heap cell referenced +by x. The value t must hold a valid cell type as described in -->data-rep. + + +Accessing Cell Entries +====================== + +For a non immediate scheme object x, the object type can be determined by +reading the cell type entry using the SCM_CELL_TYPE macro. For the different +types of cells it is known which cell entry holds scheme objects and which cell +entry holds raw C data. To access the different cell entries appropriately, +the following macros are provided: + +- scm_bits_t SCM_CELL_WORD (SCM x, unsigned int n): Deliver the cell entry n +of the heap cell referenced by the non immediate scheme object x as raw data. +It is illegal, to access cell entries that hold scheme objects by using these +macros. For convenience, the following macros are also provided: + SCM_CELL_WORD_0 (x) --> SCM_CELL_WORD (x, 0) + SCM_CELL_WORD_1 (x) --> SCM_CELL_WORD (x, 1) + ... + SCM_CELL_WORD_n (x) --> SCM_CELL_WORD (x, n) + +- SCM SCM_CELL_OBJECT (SCM x, unsigned int n): Deliver the cell entry n of +the heap cell referenced by the non immediate scheme object x as a scheme +object. It is illegal, to access cell entries that do not hold scheme objects +by using these macros. For convenience, the following macros are also +provided: + SCM_CELL_OBJECT_0 (x) --> SCM_CELL_OBJECT (x, 0) + SCM_CELL_OBJECT_1 (x) --> SCM_CELL_OBJECT (x, 1) + ... + SCM_CELL_OBJECT_n (x) --> SCM_CELL_OBJECT (x, n) + +- void SCM_SET_CELL_WORD (SCM x, unsigned int n, scm_bits_t w): Write the raw +C value w into entry number n of the heap cell referenced by the non immediate +scheme value x. Values that are written into cells this way may only be read +from the cells using the SCM_CELL_WORD macros or, in case cell entry 0 is +written, using the SCM_CELL_TYPE macro. For the special case of cell entry 0 +it has to be made sure that w contains a cell type information (see +-->data-rep) which does not describe a scheme object. For convenience, the +following macros are also provided: + SCM_SET_CELL_WORD_0 (x, w) --> SCM_SET_CELL_WORD (x, 0, w) + SCM_SET_CELL_WORD_1 (x, w) --> SCM_SET_CELL_WORD (x, 1, w) + ... + SCM_SET_CELL_WORD_n (x, w) --> SCM_SET_CELL_WORD (x, n, w) + +- void SCM_SET_CELL_OBJECT (SCM x, unsigned int n, SCM o): Write the scheme +object o into entry number n of the heap cell referenced by the non immediate +scheme value x. Values that are written into cells this way may only be read +from the cells using the SCM_CELL_OBJECT macros or, in case cell entry 0 is +written, using the SCM_CELL_TYPE macro. For the special case of cell entry 0 +the writing of a scheme object into this cell is only allowed, if the cell +forms a scheme pair. For convenience, the following macros are also provided: + SCM_SET_CELL_OBJECT_0 (x, o) --> SCM_SET_CELL_OBJECT (x, 0, o) + SCM_SET_CELL_OBJECT_1 (x, o) --> SCM_SET_CELL_OBJECT (x, 1, o) + ... + SCM_SET_CELL_OBJECT_n (x, o) --> SCM_SET_CELL_OBJECT (x, n, o) + +Summary: +* For a non immediate scheme object x of unknown type, get the type + information by using SCM_CELL_TYPE (x). +* As soon as the cell type information is available, only use the appropriate + access methods to read and write data to the different cell entries. + + +Basic Rules for Accessing Cell Entries +====================================== + +For each cell type it is generally up to the implementation of that type which +of the corresponding cell entries hold scheme objects and which hold raw C +values. However, there is one basic rules that has to be followed: Scheme +pairs consist of exactly two cell entries, which both contain scheme objects. +Further, a cell which contains a scheme object in it first entry has to be a +scheme pair. In other words, it is not allowed to store a scheme object in +the first cell entry and a non scheme object in the second cell entry. + +Fixme:shouldn't this rather be SCM_PAIRP / SCM_PAIR_P ? +- int SCM_CONSP (SCM x): Determine, whether the scheme object x is a scheme +pair, i. e. whether x references a heap cell consisting of exactly two +entries, where both entries contain a scheme object. In this case, both +entries will have to be accessed using the SCM_CELL_OBJECT macros. On the +contrary, if the SCM_CONSP predicate is not fulfilled, the first entry of the +scheme cell is guaranteed not to be a scheme value and thus the first cell +entry must be accessed using the SCM_CELL_WORD_0 macro. diff --git a/doc/appendices.texi b/doc/ref/appendices.texi index e69de29bb..e69de29bb 100644 --- a/doc/appendices.texi +++ b/doc/ref/appendices.texi diff --git a/doc/data-rep.texi b/doc/ref/data-rep.texi index 351d7fb31..137d11833 100644 --- a/doc/data-rep.texi +++ b/doc/ref/data-rep.texi @@ -46,7 +46,7 @@ @c essay @sp 10 @c essay @comment The title is printed in a large font. @c essay @title Data Representation in Guile -@c essay @subtitle $Id: data-rep.texi,v 1.26 2001-06-08 22:35:30 ossau Exp $ +@c essay @subtitle $Id: data-rep.texi,v 1.1 2001-08-24 09:40:29 ossau Exp $ @c essay @subtitle For use with Guile @value{VERSION} @c essay @author Jim Blandy @c essay @author Free Software Foundation diff --git a/doc/ref/deprecated.texi b/doc/ref/deprecated.texi new file mode 100644 index 000000000..e99e73819 --- /dev/null +++ b/doc/ref/deprecated.texi @@ -0,0 +1,138 @@ +@page +@node Deprecated +@chapter Deprecated + +@menu +* Shared And Read Only Strings:: +@end menu + + +@node Shared And Read Only Strings +@section Shared And Read Only Strings + +The procedures described in this section are deprecated because explicit +shared substrings are planned to disappear from Guile. + +Instead, all strings will be implemented using sharing internally, +combined with a copy-on-write strategy. Once internal string sharing +and copy-on-write have been implemented, it will be unnecessary to +preserve the concept of read only strings. + +@menu +* Shared Substrings:: Strings which share memory with each other. +* Read Only Strings:: Treating certain non-strings as strings. +@end menu + + +@node Shared Substrings +@subsection Shared Substrings + +Whenever you extract a substring using @code{substring}, the Scheme +interpreter allocates a new string and copies data from the old string. +This is expensive, but @code{substring} is so convenient for +manipulating text that programmers use it often. + +Guile Scheme provides the concept of the @dfn{shared substring} to +improve performance of many substring-related operations. A shared +substring is an object that mostly behaves just like an ordinary +substring, except that it actually shares storage space with its parent +string. + +@deffn primitive make-shared-substring str [start [end]] +Return a shared substring of @var{str}. The arguments are the +same as for the @code{substring} function: the shared substring +returned includes all of the text from @var{str} between +indexes @var{start} (inclusive) and @var{end} (exclusive). If +@var{end} is omitted, it defaults to the end of @var{str}. The +shared substring returned by @code{make-shared-substring} +occupies the same storage space as @var{str}. +@end deffn + +Example: + +@example +(define foo "the quick brown fox") +(define bar (make-shared-substring some-string 4 9)) + +foo => "t h e q u i c k b r o w n f o x" +bar =========> |---------| +@end example + +The shared substring @var{bar} is not given its own storage space. +Instead, the Guile interpreter notes internally that @var{bar} points to +a portion of the memory allocated to @var{foo}. However, @var{bar} +behaves like an ordinary string in most respects: it may be used with +string primitives like @code{string-length}, @code{string-ref}, +@code{string=?}. Guile makes the necessary translation between indices +of @var{bar} and indices of @var{foo} automatically. + +@example +(string-length? bar) @result{} 5 ; bar only extends from indices 4 to 9 +(string-ref bar 3) @result{} #\c ; same as (string-ref foo 7) +(make-shared-substring bar 2) + @result{} "ick" ; can even make a shared substring! +@end example + +Because creating a shared substring does not require allocating new +storage from the heap, it is a very fast operation. However, because it +shares memory with its parent string, a change to the contents of the +parent string will implicitly change the contents of its shared +substrings. + +@example +(string-set! foo 7 #\r) +bar @result{} "quirk" +@end example + +Guile considers shared substrings to be immutable. This is because +programmers might not always be aware that a given string is really a +shared substring, and might innocently try to mutate it without +realizing that the change would affect its parent string. (We are +currently considering a "copy-on-write" strategy that would permit +modifying shared substrings without affecting the parent string.) + +In general, shared substrings are useful in circumstances where it is +important to divide a string into smaller portions, but you do not +expect to change the contents of any of the strings involved. + + +@node Read Only Strings +@subsection Read Only Strings + +In previous versions of Guile, there was the idea that some string-based +primitives such as @code{string-append} could equally accept symbols as +arguments. For example, one could write + +@lisp +(string-append '/home/ 'vigilia) +@end lisp + +@noindent +and get @code{"/home/vigilia"} as the result. The term @dfn{read only +string} was adopted to describe the argument type expected by such +primitives. + +This idea has now been removed. The predicate @code{read-only-string?} +still exists, but deprecated, and is equivalent to + +@lisp +(lambda (x) (or (string? x) (symbol? x))) +@end lisp + +@noindent +But no Guile primitives now use @code{read-only-string?} to validate +their arguments. + +String-based primitives such as @code{string-append} +now require strings: + +@lisp +(string-append '/home/ 'vigilia) +@result{} +ERROR: Wrong type argument (expecting STRINGP): /home/ +@end lisp + +@deffn primitive read-only-string? obj +Return @code{#t} if @var{obj} is either a string or a symbol, +otherwise return @code{#f}. +@end deffn diff --git a/doc/ref/expect.texi b/doc/ref/expect.texi new file mode 100644 index 000000000..7e169e428 --- /dev/null +++ b/doc/ref/expect.texi @@ -0,0 +1,142 @@ +@page +@node Expect +@chapter Expect + +The macros in this section are made available with: + +@smalllisp +(use-modules (ice-9 expect)) +@end smalllisp + +@code{expect} is a macro for selecting actions based on the output from +a port. The name comes from a tool of similar functionality by Don Libes. +Actions can be taken when a particular string is matched, when a timeout +occurs, or when end-of-file is seen on the port. The @code{expect} macro +is described below; @code{expect-strings} is a front-end to @code{expect} +based on regexec (see the regular expression documentation). + +@defmac expect-strings clause @dots{} +By default, @code{expect-strings} will read from the current input port. +The first term in each clause consists of an expression evaluating to +a string pattern (regular expression). As characters +are read one-by-one from the port, they are accumulated in a buffer string +which is matched against each of the patterns. When a +pattern matches, the remaining expression(s) in +the clause are evaluated and the value of the last is returned. For example: + +@smalllisp +(with-input-from-file "/etc/passwd" + (lambda () + (expect-strings + ("^nobody" (display "Got a nobody user.\n") + (display "That's no problem.\n")) + ("^daemon" (display "Got a daemon user.\n"))))) +@end smalllisp + +The regular expression is compiled with the @code{REG_NEWLINE} flag, so +that the ^ and $ anchors will match at any newline, not just at the start +and end of the string. + +There are two other ways to write a clause: + +The expression(s) to evaluate +can be omitted, in which case the result of the regular expression match +(converted to strings, as obtained from regexec with match-pick set to "") +will be returned if the pattern matches. + +The symbol @code{=>} can be used to indicate that the expression is a +procedure which will accept the result of a successful regular expression +match. E.g., + +@smalllisp +("^daemon" => write) +("^d\\(aemon\\)" => (lambda args (for-each write args))) +("^da\\(em\\)on" => (lambda (all sub) + (write all) (newline) + (write sub) (newline))) +@end smalllisp + +The order of the substrings corresponds to the order in which the +opening brackets occur. + +A number of variables can be used to control the behaviour +of @code{expect} (and @code{expect-strings}). +Most have default top-level bindings to the value @code{#f}, +which produces the default behaviour. +They can be redefined at the +top level or locally bound in a form enclosing the expect expression. + +@table @code +@item expect-port +A port to read characters from, instead of the current input port. +@item expect-timeout +@code{expect} will terminate after this number of +seconds, returning @code{#f} or the value returned by expect-timeout-proc. +@item expect-timeout-proc +A procedure called if timeout occurs. The procedure takes a single argument: +the accumulated string. +@item expect-eof-proc +A procedure called if end-of-file is detected on the input port. The +procedure takes a single argument: the accumulated string. +@item expect-char-proc +A procedure to be called every time a character is read from the +port. The procedure takes a single argument: the character which was read. +@item expect-strings-compile-flags +Flags to be used when compiling a regular expression, which are passed +to @code{make-regexp} @xref{Regexp Functions}. The default value +is @code{regexp/newline}. +@item expect-strings-exec-flags +Flags to be used when executing a regular expression, which are +passed to regexp-exec @xref{Regexp Functions}. +The default value is @code{regexp/noteol}, which prevents @code{$} +from matching the end of the string while it is still accumulating, +but still allows it to match after a line break or at the end of file. +@end table + +Here's an example using all of the variables: + +@smalllisp +(let ((expect-port (open-input-file "/etc/passwd")) + (expect-timeout 1) + (expect-timeout-proc + (lambda (s) (display "Times up!\n"))) + (expect-eof-proc + (lambda (s) (display "Reached the end of the file!\n"))) + (expect-char-proc display) + (expect-strings-compile-flags (logior regexp/newline regexp/icase)) + (expect-strings-exec-flags 0)) + (expect-strings + ("^nobody" (display "Got a nobody user\n")))) +@end smalllisp +@end defmac + +@defmac expect clause @dots{} +@code{expect} is used in the same way as @code{expect-strings}, +but tests are specified not as patterns, but as procedures. The +procedures are called in turn after each character is read from the +port, with two arguments: the value of the accumulated string and +a flag to indicate whether end-of-file has been reached. The flag +will usually be @code{#f}, but if end-of-file is reached, the procedures +are called an additional time with the final accumulated string and +@code{#t}. + +The test is successful if the procedure returns a non-false value. + +If the @code{=>} syntax is used, then if the test succeeds it must return +a list containing the arguments to be provided to the corresponding +expression. + +In the following example, a string will only be matched at the beginning +of the file: + +@smalllisp +(let ((expect-port (open-input-file "/etc/passwd"))) + (expect + ((lambda (s eof?) (string=? s "fnord!")) + (display "Got a nobody user!\n")))) +@end smalllisp + +The control variables described for @code{expect-strings} also +influence the behaviour of @code{expect}, with the exception of +variables whose names begin with @code{expect-strings-}. +@end defmac diff --git a/doc/ref/extend.texi b/doc/ref/extend.texi new file mode 100644 index 000000000..5c72bef33 --- /dev/null +++ b/doc/ref/extend.texi @@ -0,0 +1,44 @@ +@page +@node Libguile Intro +@chapter Using Guile as an Extension Language + +The chapters in this part of the manual explain how to use Guile as a +powerful application extension language. + +An important change for the 1.6.x series of Guile releases is that the +GH interface is now deprecated. For the reasoning behind this decision, +see @xref{GH deprecation}. The GH interface will continue to be +supported for the 1.6.x and 1.8.x release series, but will be dropped +thereafter, so developers are encouraged to switch progressively to the +scm interface. The last chapter in this part of the manual (@pxref{GH}) +documents both how to use GH and how to switch from GH to scm. + +The Guile developers believe that clarification of the GH vs. scm +debate, and the consequent deprecation of the GH interface, are in the +long term interests of the project. However it does create an +unfortunate situation for developers who want to start a project using +Guile and so read the manual to find out how to proceed. They will +discover that the GH interface, although quite well documented, is +deprecated, but that there is almost no adequate documentation for its +theoretical replacement, the scm interface. Moreover, the scm interface +still has the odd few rough edges which need smoothing down. + +Therefore, although deprecated, it is quite OK to continue to use the GH +interface if you feel uncomfortable with the `scm_' interface as it +stands today. By the time that support for GH is dropped, we plan to +have thoroughly documented the `scm_' interface, and to have enhanced it +such that conversion from GH to the `scm_' interface will be very +straightforward, and probably mostly automated. + +As far as documentation of the scm interface is concerned, the current +position is that it is a bit confused, but that the situation should +improve rapidly once the 1.6.0 release is out. The plan is to refocus +the bulk of Part II, currently ``Guile Scheme'', as the ``Guile API +Reference'' so that it covers both Scheme and C interfaces. (This makes +sense because almost all of Guile's primitive procedures on the Scheme +level --- e.g. @code{memq} --- are also available as C level primitives +in the scm interface --- e.g. @code{scm_memq}.) There will then remain +a certain amount of Scheme-specific (such as the ``Basic Ideas'' +chapter) and C-specific documentation (such as SMOB usage and +interaction with the garbage collector) to collect into corresponding +chapters. diff --git a/doc/ref/gh.texi b/doc/ref/gh.texi new file mode 100644 index 000000000..15d89c18f --- /dev/null +++ b/doc/ref/gh.texi @@ -0,0 +1,1164 @@ +@page +@node GH +@chapter GH: A Portable C to Scheme Interface +@cindex libguile - gh +@cindex gh +@cindex gh - reference manual + +This chapter shows how to use the GH interface to call Guile from your +application's C code, and to add new Scheme level procedures to Guile +whose behaviour is specified by application specific code written in C. + +Note, however, that the GH interface is now deprecated, and developers +are encouraged to switch to using the scm interface instead. Therefore, +for each GH feature, this chapter should also document how to achieve +the same result using the scm interface. + +@menu +* GH deprecation:: Why the GH interface is now deprecated. +* gh preliminaries:: +* Data types and constants defined by gh:: +* Starting and controlling the interpreter:: +* Error messages:: +* Executing Scheme code:: +* Defining new Scheme procedures in C:: +* Converting data between C and Scheme:: +* Type predicates:: +* Equality predicates:: +* Memory allocation and garbage collection:: +* Calling Scheme procedures from C:: +* Mixing gh and scm APIs:: +* scm transition summary:: +@end menu + + +@node GH deprecation +@section Why the GH Interface is Now Deprecated + +Historically, the GH interface was the product of a practical problem +and a neat idea. The practical problem was that the interface of the +@code{scm_} functions with which Guile itself was written (inherited +from Aubrey Jaffer's SCM) was so closely tied to the (rather arcane) +details of the internal data representation that it was extremely +difficult to write a Guile extension using these functions. The neat +idea was to define a high level language extension interface in such a +way that other extension language projects, not just Guile, would be +able to provide an implementation of that interface; then applications +using this interface could be compiled with whichever of the various +available implementations they chose. So the GH interface was created, +and advertised both as the recommended interface for application +developers wishing to use Guile, and as a portable high level interface +that could theoretically be implemented by other extension language +projects. + +Time passed, and various things changed. Crucially, an enormous number +of improvements were made to the @code{scm_} interface that Guile itself +uses in its implementation, with the result that it is now both easy and +comfortable to write a Guile extension with this interface. At the same +time, the contents of the GH interface were somewhat neglected by the +core Guile developers, such that some key operations --- such as smob +creation and management --- are simply not possible using GH alone. +Finally, the idea of multiple implementations of the GH interface did +not really crystallize (apart, I believe, from a short lived +implementation by the MzScheme project). + +For all these reasons, the Guile developers have decided to deprecate +the GH interface --- which means that support for GH will be completely +removed after the next few releases --- and to focus only on the +@code{scm_} interface, with additions to ensure that it is as easy to +use in all respects as GH was. + +It remains an open question whether a deep kind of interface portability +would be useful for extension language-based applications, and it may +still be an interesting project to attempt to define a corresponding +GH-like interface, but the Guile developers no longer plan to try to do +this as part of the core Guile project. + + +@node gh preliminaries +@section gh preliminaries + +To use gh, you must have the following toward the beginning of your C +source: +@smallexample +#include <guile/gh.h> +@end smallexample +@cindex gh - headers + +When you link, you will have to add at least @code{-lguile} to the list +of libraries. If you are using more of Guile than the basic Scheme +interpreter, you will have to add more libraries. +@cindex gh - linking + + +@node Data types and constants defined by gh +@section Data types and constants defined by gh +@cindex libguile - data types + +The following C constants and data types are defined in gh: + +@deftp {Data type} SCM +This is a C data type used to store all Scheme data, no matter what the +Scheme type. Values are converted between C data types and the SCM type +with utility functions described below (@pxref{Converting data between C +and Scheme}). [FIXME: put in references to Jim's essay and so forth.] +@end deftp +@cindex SCM data type + +@defvr Constant SCM_BOOL_T +@defvrx Constant SCM_BOOL_F +The @emph{Scheme} values returned by many boolean procedures in +libguile. + +This can cause confusion because they are different from 0 and 1. In +testing a boolean function in libguile programming, you must always make +sure that you check the spec: @code{gh_} and @code{scm_} functions will +usually return @code{SCM_BOOL_T} and @code{SCM_BOOL_F}, but other C +functions usually can be tested against 0 and 1, so programmers' fingers +tend to just type @code{if (boolean_function()) @{ ... @}} +@end defvr + +@defvr Constant SCM_UNSPECIFIED +This is a SCM value that is not the same as any legal Scheme value. It +is the value that a Scheme function returns when its specification says +that its return value is unspecified. +@end defvr + +@defvr Constant SCM_UNDEFINED +This is another SCM value that is not the same as any legal Scheme +value. It is the value used to mark variables that do not yet have a +value, and it is also used in C to terminate functions with variable +numbers of arguments, such as @code{gh_list()}. +@end defvr + + +@node Starting and controlling the interpreter +@section Starting and controlling the interpreter +@cindex libguile - start interpreter + +In almost every case, your first @code{gh_} call will be: + +@deftypefun void gh_enter (int @var{argc}, char *@var{argv}[], void (*@var{main_prog})()) +Starts up a Scheme interpreter with all the builtin Scheme primitives. +@code{gh_enter()} never exits, and the user's code should all be in the +@code{@var{main_prog}()} function. @code{argc} and @code{argv} will be +passed to @var{main_prog}. + +@deftypefun void main_prog (int @var{argc}, char *@var{argv}[]) +This is the user's main program. It will be invoked by +@code{gh_enter()} after Guile has been started up. +@end deftypefun + +Note that you can use @code{gh_repl} inside @code{gh_enter} (in other +words, inside the code for @code{main-prog}) if you want the program to +be controled by a Scheme read-eval-print loop. +@end deftypefun + +@cindex read eval print loop -- from the gh_ interface +@cindex REPL -- from the gh_ interface +A convenience routine which enters the Guile interpreter with the +standard Guile read-eval-print loop (@dfn{REPL}) is: + +@deftypefun void gh_repl (int @var{argc}, char *@var{argv}[]) +Enters the Scheme interpreter giving control to the Scheme REPL. +Arguments are processed as if the Guile program @file{guile} were being +invoked. + +Note that @code{gh_repl} should be used @emph{inside} @code{gh_enter}, +since any Guile interpreter calls are meaningless unless they happen in +the context of the interpreter. + +Also note that when you use @code{gh_repl}, your program will be +controlled by Guile's REPL (which is written in Scheme and has many +useful features). Use straight C code inside @code{gh_enter} if you +want to maintain execution control in your C program. +@end deftypefun + +You will typically use @code{gh_enter} and @code{gh_repl} when you +want a Guile interpreter enhanced by your own libraries, but otherwise +quite normal. For example, to build a Guile--derived program that +includes some random number routines @dfn{GSL} (GNU Scientific Library), +you would write a C program that looks like this: + +@smallexample +#include <guile/gh.h> +#include <gsl_ran.h> + +/* random number suite */ +SCM gw_ran_seed(SCM s) +@{ + gsl_ran_seed(gh_scm2int(s)); + return SCM_UNSPECIFIED; +@} + +SCM gw_ran_random() +@{ + SCM x; + + x = gh_ulong2scm(gsl_ran_random()); + return x; +@} + +SCM gw_ran_uniform() +@{ + SCM x; + + x = gh_double2scm(gsl_ran_uniform()); + return x; +@} +SCM gw_ran_max() +@{ + return gh_double2scm(gsl_ran_max()); +@} + +void +init_gsl() +@{ + /* random number suite */ + gh_new_procedure("gsl-ran-seed", gw_ran_seed, 1, 0, 0); + gh_new_procedure("gsl-ran-random", gw_ran_random, 0, 0, 0); + gh_new_procedure("gsl-ran-uniform", gw_ran_uniform, 0, 0, 0); + gh_new_procedure("gsl-ran-max", gw_ran_max, 0, 0, 0); +@} + +void +main_prog (int argc, char *argv[]) +@{ + init_gsl(); + + gh_repl(argc, argv); +@} + +int +main (int argc, char *argv[]) +@{ + gh_enter (argc, argv, main_prog); +@} +@end smallexample + +Then, supposing the C program is in @file{guile-gsl.c}, you could +compile it with @kbd{gcc -o guile-gsl guile-gsl.c -lguile -lgsl}. + +The resulting program @file{guile-gsl} would have new primitive +procedures @code{gsl-ran-random}, @code{gsl-ran-gaussian} and so forth. + + +@node Error messages +@section Error messages +@cindex libguile - error messages +@cindex error messages in libguile + +[FIXME: need to fill this based on Jim's new mechanism] + + +@node Executing Scheme code +@section Executing Scheme code +@cindex libguile - executing Scheme +@cindex executing Scheme + +Once you have an interpreter running, you can ask it to evaluate Scheme +code. There are two calls that implement this: + +@deftypefun SCM gh_eval_str (char *@var{scheme_code}) +This asks the interpreter to evaluate a single string of Scheme code, +and returns the result of the last expression evaluated. + +Note that the line of code in @var{scheme_code} must be a well formed +Scheme expression. If you have many lines of code before you balance +parentheses, you must either concatenate them into one string, or use +@code{gh_eval_file()}. +@end deftypefun + +@deftypefun SCM gh_eval_file (char *@var{fname}) +@deftypefunx SCM gh_load (char *@var{fname}) +@code{gh_eval_file} is completely analogous to @code{gh_eval_str()}, +except that a whole file is evaluated instead of a string. +@code{gh_eval_file} returns @code{SCM_UNSPECIFIED}. + +@code{gh_load} is identical to @code{gh_eval_file} (it's a macro that +calls @code{gh_eval_file} on its argument). It is provided to start +making the @code{gh_} interface match the R5RS Scheme procedures +closely. +@end deftypefun + + +@node Defining new Scheme procedures in C +@section Defining new Scheme procedures in C +@cindex libguile - new procedures +@cindex new procedures +@cindex procedures, new +@cindex new primitives +@cindex primitives, new + +The real interface between C and Scheme comes when you can write new +Scheme procedures in C. This is done through the routine + + +@deftypefn {Libguile high} SCM gh_new_procedure (char *@var{proc_name}, SCM (*@var{fn})(), int @var{n_required_args}, int @var{n_optional_args}, int @var{restp}) +@code{gh_new_procedure} defines a new Scheme procedure. Its Scheme name +will be @var{proc_name}, it will be implemented by the C function +(*@var{fn})(), it will take at least @var{n_required_args} arguments, +and at most @var{n_optional_args} extra arguments. + +When the @var{restp} parameter is 1, the procedure takes a final +argument: a list of remaining parameters. + +@code{gh_new_procedure} returns an SCM value representing the procedure. + +The C function @var{fn} should have the form +@deftypefn {Libguile high} SCM fn (SCM @var{req1}, SCM @var{req2}, ..., SCM @var{opt1}, SCM @var{opt2}, ..., SCM @var{rest_args}) +The arguments are all passed as SCM values, so the user will have to use +the conversion functions to convert to standard C types. + +Examples of C functions used as new Scheme primitives can be found in +the sample programs @code{learn0} and @code{learn1}. +@end deftypefn + +@end deftypefn + +@strong{Rationale:} this is the correct way to define new Scheme +procedures in C. The ugly mess of arguments is required because of how +C handles procedures with variable numbers of arguments. + +@strong{Note:} what about documentation strings? + +@cartouche +There are several important considerations to be made when writing the C +routine @code{(*fn)()}. + +First of all the C routine has to return type @code{SCM}. + +Second, all arguments passed to the C funcion will be of type +@code{SCM}. + +Third: the C routine is now subject to Scheme flow control, which means +that it could be interrupted at any point, and then reentered. This +means that you have to be very careful with operations such as +allocating memory, modifying static data @dots{} + +Fourth: to get around the latter issue, you can use +@code{GH_DEFER_INTS} and @code{GH_ALLOW_INTS}. +@end cartouche + +@defmac GH_DEFER_INTS +@defmacx GH_ALLOW_INTS +These macros disable and reenable Scheme's flow control. They +@end defmac + + +@c [??? have to do this right; maybe using subsections, or maybe creating a +@c section called Flow control issues...] + +@c [??? Go into exhaustive detail with examples of the various possible +@c combinations of required and optional args...] + + +@node Converting data between C and Scheme +@section Converting data between C and Scheme +@cindex libguile - converting data +@cindex data conversion +@cindex converting data + +Guile provides mechanisms to convert data between C and Scheme. This +allows new builtin procedures to understand their arguments (which are +of type @code{SCM}) and return values of type @code{SCM}. + + +@menu +* C to Scheme:: +* Scheme to C:: +@end menu + +@node C to Scheme +@subsection C to Scheme + +@deftypefun SCM gh_bool2scm (int @var{x}) +Returns @code{#f} if @var{x} is zero, @code{#t} otherwise. +@end deftypefun + +@deftypefun SCM gh_ulong2scm (unsigned long @var{x}) +@deftypefunx SCM gh_long2scm (long @var{x}) +@deftypefunx SCM gh_double2scm (double @var{x}) +@deftypefunx SCM gh_char2scm (char @var{x}) +Returns a Scheme object with the value of the C quantity @var{x}. +@end deftypefun + +@deftypefun SCM gh_str2scm (char *@var{s}, int @var{len}) +Returns a new Scheme string with the (not necessarily null-terminated) C +array @var{s} data. +@end deftypefun + +@deftypefun SCM gh_str02scm (char *@var{s}) +Returns a new Scheme string with the null-terminated C string @var{s} +data. +@end deftypefun + +@deftypefun SCM gh_set_substr (char *@var{src}, SCM @var{dst}, int @var{start}, int @var{len}) +Copy @var{len} characters at @var{src} into the @emph{existing} Scheme +string @var{dst}, starting at @var{start}. @var{start} is an index into +@var{dst}; zero means the beginning of the string. + +If @var{start} + @var{len} is off the end of @var{dst}, signal an +out-of-range error. +@end deftypefun + +@deftypefun SCM gh_symbol2scm (char *@var{name}) +Given a null-terminated string @var{name}, return the symbol with that +name. +@end deftypefun + +@deftypefun SCM gh_ints2scm (int *@var{dptr}, int @var{n}) +@deftypefunx SCM gh_doubles2scm (double *@var{dptr}, int @var{n}) +Make a scheme vector containing the @var{n} ints or doubles at memory +location @var{dptr}. +@end deftypefun + +@deftypefun SCM gh_chars2byvect (char *@var{dptr}, int @var{n}) +@deftypefunx SCM gh_shorts2svect (short *@var{dptr}, int @var{n}) +@deftypefunx SCM gh_longs2ivect (long *@var{dptr}, int @var{n}) +@deftypefunx SCM gh_ulongs2uvect (ulong *@var{dptr}, int @var{n}) +@deftypefunx SCM gh_floats2fvect (float *@var{dptr}, int @var{n}) +@deftypefunx SCM gh_doubles2dvect (double *@var{dptr}, int @var{n}) +Make a scheme uniform vector containing the @var{n} chars, shorts, +longs, unsigned longs, floats or doubles at memory location @var{dptr}. +@end deftypefun + + + +@node Scheme to C +@subsection Scheme to C + +@deftypefun int gh_scm2bool (SCM @var{obj}) +@deftypefunx {unsigned long} gh_scm2ulong (SCM @var{obj}) +@deftypefunx long gh_scm2long (SCM @var{obj}) +@deftypefunx double gh_scm2double (SCM @var{obj}) +@deftypefunx int gh_scm2char (SCM @var{obj}) +These routines convert the Scheme object to the given C type. +@end deftypefun + +@deftypefun char *gh_scm2newstr (SCM @var{str}, int *@var{lenp}) +Given a Scheme string @var{str}, return a pointer to a new copy of its +contents, followed by a null byte. If @var{lenp} is non-null, set +@code{*@var{lenp}} to the string's length. + +This function uses malloc to obtain storage for the copy; the caller is +responsible for freeing it. + +Note that Scheme strings may contain arbitrary data, including null +characters. This means that null termination is not a reliable way to +determine the length of the returned value. However, the function +always copies the complete contents of @var{str}, and sets @var{*lenp} +to the true length of the string (when @var{lenp} is non-null). +@end deftypefun + + +@deftypefun void gh_get_substr (SCM str, char *return_str, int *lenp) +Copy @var{len} characters at @var{start} from the Scheme string +@var{src} to memory at @var{dst}. @var{start} is an index into +@var{src}; zero means the beginning of the string. @var{dst} has +already been allocated by the caller. + +If @var{start} + @var{len} is off the end of @var{src}, signal an +out-of-range error. +@end deftypefun + +@deftypefun char *gh_symbol2newstr (SCM @var{sym}, int *@var{lenp}) +Takes a Scheme symbol and returns a string of the form +@code{"'symbol-name"}. If @var{lenp} is non-null, the string's length +is returned in @code{*@var{lenp}}. + +This function uses malloc to obtain storage for the returned string; the +caller is responsible for freeing it. +@end deftypefun + +@deftypefun char *gh_scm2chars (SCM @var{vector}, chars *@var{result}) +@deftypefunx short *gh_scm2shorts (SCM @var{vector}, short *@var{result}) +@deftypefunx long *gh_scm2longs (SCM @var{vector}, long *@var{result}) +@deftypefunx float *gh_scm2floats (SCM @var{vector}, float *@var{result}) +@deftypefunx double *gh_scm2doubles (SCM @var{vector}, double *@var{result}) +Copy the numbers in @var{vector} to the array pointed to by @var{result} +and return it. If @var{result} is NULL, allocate a double array large +enough. + +@var{vector} can be an ordinary vector, a weak vector, or a signed or +unsigned uniform vector of the same type as the result array. For +chars, @var{vector} can be a string or substring. For floats and +doubles, @var{vector} can contain a mix of inexact and integer values. + +If @var{vector} is of unsigned type and contains values too large to fit +in the signed destination array, those values will be wrapped around, +that is, data will be copied as if the destination array was unsigned. +@end deftypefun + + +@node Type predicates +@section Type predicates + +These C functions mirror Scheme's type predicate procedures with one +important difference. The C routines return C boolean values (0 and 1) +instead of @code{SCM_BOOL_T} and @code{SCM_BOOL_F}. + +The Scheme notational convention of putting a @code{?} at the end of +predicate procedure names is mirrored in C by placing @code{_p} at the +end of the procedure. For example, @code{(pair? ...)} maps to +@code{gh_pair_p(...)}. + +@deftypefun int gh_boolean_p (SCM @var{val}) +Returns 1 if @var{val} is a boolean, 0 otherwise. +@end deftypefun + +@deftypefun int gh_symbol_p (SCM @var{val}) +Returns 1 if @var{val} is a symbol, 0 otherwise. +@end deftypefun + +@deftypefun int gh_char_p (SCM @var{val}) +Returns 1 if @var{val} is a char, 0 otherwise. +@end deftypefun + +@deftypefun int gh_vector_p (SCM @var{val}) +Returns 1 if @var{val} is a vector, 0 otherwise. +@end deftypefun + +@deftypefun int gh_pair_p (SCM @var{val}) +Returns 1 if @var{val} is a pair, 0 otherwise. +@end deftypefun + +@deftypefun int gh_procedure_p (SCM @var{val}) +Returns 1 if @var{val} is a procedure, 0 otherwise. +@end deftypefun + +@deftypefun int gh_list_p (SCM @var{val}) +Returns 1 if @var{val} is a list, 0 otherwise. +@end deftypefun + +@deftypefun int gh_inexact_p (SCM @var{val}) +Returns 1 if @var{val} is an inexact number, 0 otherwise. +@end deftypefun + +@deftypefun int gh_exact_p (SCM @var{val}) +Returns 1 if @var{val} is an exact number, 0 otherwise. +@end deftypefun + + +@node Equality predicates +@section Equality predicates + +These C functions mirror Scheme's equality predicate procedures with one +important difference. The C routines return C boolean values (0 and 1) +instead of @code{SCM_BOOL_T} and @code{SCM_BOOL_F}. + +The Scheme notational convention of putting a @code{?} at the end of +predicate procedure names is mirrored in C by placing @code{_p} at the +end of the procedure. For example, @code{(equal? ...)} maps to +@code{gh_equal_p(...)}. + +@deftypefun int gh_eq_p (SCM x, SCM y) +Returns 1 if @var{x} and @var{y} are equal in the sense of Scheme's +@code{eq?} predicate, 0 otherwise. +@end deftypefun + +@deftypefun int gh_eqv_p (SCM x, SCM y) +Returns 1 if @var{x} and @var{y} are equal in the sense of Scheme's +@code{eqv?} predicate, 0 otherwise. +@end deftypefun + +@deftypefun int gh_equal_p (SCM x, SCM y) +Returns 1 if @var{x} and @var{y} are equal in the sense of Scheme's +@code{equal?} predicate, 0 otherwise. +@end deftypefun + +@deftypefun int gh_string_equal_p (SCM @var{s1}, SCM @var{s2}) +Returns 1 if the strings @var{s1} and @var{s2} are equal, 0 otherwise. +@end deftypefun + +@deftypefun int gh_null_p (SCM @var{l}) +Returns 1 if @var{l} is an empty list or pair; 0 otherwise. +@end deftypefun + + +@node Memory allocation and garbage collection +@section Memory allocation and garbage collection + +@c [FIXME: flesh this out with some description of garbage collection in +@c scm/guile] + +@c @deftypefun SCM gh_mkarray (int size) +@c Allocate memory for a Scheme object in a garbage-collector-friendly +@c manner. +@c @end deftypefun + + +@node Calling Scheme procedures from C +@section Calling Scheme procedures from C + +Many of the Scheme primitives are available in the @code{gh_} +interface; they take and return objects of type SCM, and one could +basically use them to write C code that mimics Scheme code. + +I will list these routines here without much explanation, since what +they do is the same as documented in @ref{Standard procedures, R5RS, , +r5rs, R5RS}. But I will point out that when a procedure takes a +variable number of arguments (such as @code{gh_list}), you should pass +the constant @var{SCM_UNDEFINED} from C to signify the end of the list. + +@deftypefun SCM gh_define (char *@var{name}, SCM @var{val}) +Corresponds to the Scheme @code{(define name val)}: it binds a value to +the given name (which is a C string). Returns the new object. +@end deftypefun + +@heading Pairs and lists + +@deftypefun SCM gh_cons (SCM @var{a}, SCM @var{b}) +@deftypefunx SCM gh_list (SCM l0, SCM l1, ... , SCM_UNDEFINED) +These correspond to the Scheme @code{(cons a b)} and @code{(list l0 l1 +...)} procedures. Note that @code{gh_list()} is a C macro that invokes +@code{scm_listify()}. +@end deftypefun + +@deftypefun SCM gh_car (SCM @var{obj}) +@deftypefunx SCM gh_cdr (SCM @var{obj}) +@dots{} + +@deftypefunx SCM gh_c[ad][ad][ad][ad]r (SCM @var{obj}) +These correspond to the Scheme @code{(caadar ls)} procedures etc @dots{} +@end deftypefun + +@deftypefun SCM gh_set_car_x(SCM @var{pair}, SCM @var{value}) +Modifies the CAR of @var{pair} to be @var{value}. This is equivalent to +the Scheme procedure @code{(set-car! ...)}. +@end deftypefun + +@deftypefun SCM gh_set_cdr_x(SCM @var{pair}, SCM @var{value}) +Modifies the CDR of @var{pair} to be @var{value}. This is equivalent to +the Scheme procedure @code{(set-cdr! ...)}. +@end deftypefun + +@deftypefun {unsigned long} gh_length (SCM @var{ls}) +Returns the length of the list. +@end deftypefun + +@deftypefun SCM gh_append (SCM @var{args}) +@deftypefunx SCM gh_append2 (SCM @var{l1}, SCM @var{l2}) +@deftypefunx SCM gh_append3 (SCM @var{l1}, SCM @var{l2}, @var{l3}) +@deftypefunx SCM gh_append4 (SCM @var{l1}, SCM @var{l2}, @var{l3}, @var{l4}) +@code{gh_append()} takes @var{args}, which is a list of lists +@code{(list1 list2 ...)}, and returns a list containing all the elements +of the individual lists. + +A typical invocation of @code{gh_append()} to append 5 lists together +would be +@smallexample + gh_append(gh_list(l1, l2, l3, l4, l5, SCM_UNDEFINED)); +@end smallexample + +The functions @code{gh_append2()}, @code{gh_append2()}, +@code{gh_append3()} and @code{gh_append4()} are convenience routines to +make it easier for C programs to form the list of lists that goes as an +argument to @code{gh_append()}. +@end deftypefun + +@deftypefun SCM gh_reverse (SCM @var{ls}) +Returns a new list that has the same elements as @var{ls} but in the +reverse order. Note that this is implemented as a macro which calls +@code{scm_reverse()}. +@end deftypefun + +@deftypefun SCM gh_list_tail (SCM @var{ls}, SCM @var{k}) +Returns the sublist of @var{ls} with the last @var{k} elements. +@end deftypefun + +@deftypefun SCM gh_list_ref (SCM @var{ls}, SCM @var{k}) +Returns the @var{k}th element of the list @var{ls}. +@end deftypefun + +@deftypefun SCM gh_memq (SCM @var{x}, SCM @var{ls}) +@deftypefunx SCM gh_memv (SCM @var{x}, SCM @var{ls}) +@deftypefunx SCM gh_member (SCM @var{x}, SCM @var{ls}) +These functions return the first sublist of @var{ls} whose CAR is +@var{x}. They correspond to @code{(memq x ls)}, @code{(memv x ls)} and +@code{(member x ls)}, and hence use (respectively) @code{eq?}, +@code{eqv?} and @code{equal?} to do comparisons. + +If @var{x} does not appear in @var{ls}, the value @code{SCM_BOOL_F} (not +the empty list) is returned. + +Note that these functions are implemented as macros which call +@code{scm_memq()}, @code{scm_memv()} and @code{scm_member()} +respectively. +@end deftypefun + +@deftypefun SCM gh_assq (SCM @var{x}, SCM @var{alist}) +@deftypefunx SCM gh_assv (SCM @var{x}, SCM @var{alist}) +@deftypefunx SCM gh_assoc (SCM @var{x}, SCM @var{alist}) +These functions search an @dfn{association list} (list of pairs) +@var{alist} for the first pair whose CAR is @var{x}, and they return +that pair. + +If no pair in @var{alist} has @var{x} as its CAR, the value +@code{SCM_BOOL_F} (not the empty list) is returned. + +Note that these functions are implemented as macros which call +@code{scm_assq()}, @code{scm_assv()} and @code{scm_assoc()} +respectively. +@end deftypefun + + +@heading Symbols + +@c @deftypefun SCM gh_symbol (SCM str, SCM len) +@c @deftypefunx SCM gh_tmp_symbol (SCM str, SCM len) +@c Takes the given string @var{str} of length @var{len} and returns a +@c symbol corresponding to that string. +@c @end deftypefun + + +@heading Vectors + +@deftypefun SCM gh_make_vector (SCM @var{n}, SCM @var{fill}) +@deftypefunx SCM gh_vector (SCM @var{ls}) +@deftypefunx SCM gh_vector_ref (SCM @var{v}, SCM @var{i}) +@deftypefunx SCM gh_vector_set (SCM @var{v}, SCM @var{i}, SCM @var{val}) +@deftypefunx {unsigned long} gh_vector_length (SCM @var{v}) +@deftypefunx SCM gh_list_to_vector (SCM @var{ls}) +These correspond to the Scheme @code{(make-vector n fill)}, +@code{(vector a b c ...)} @code{(vector-ref v i)} @code{(vector-set v i +value)} @code{(vector-length v)} @code{(list->vector ls)} procedures. + +The correspondence is not perfect for @code{gh_vector}: this routine +taks a list @var{ls} instead of the individual list elements, thus +making it identical to @code{gh_list_to_vector}. + +There is also a difference in gh_vector_length: the value returned is a +C @code{unsigned long} instead of an SCM object. +@end deftypefun + + +@heading Procedures + +@c @deftypefun SCM gh_make_subr (SCM (*@var{fn})(), int @var{req}, int @var{opt}, int @var{restp}, char *@var{sym}) +@c Make the C function @var{fn} available to Scheme programs. The function +@c will be bound to the symbol @var{sym}. The arguments @var{req}, +@c @var{opt} and @var{restp} describe @var{fn}'s calling conventions. The +@c function must take @var{req} required arguments and may take @var{opt} +@c optional arguments. Any optional arguments which are not supplied by +@c the caller will be bound to @var{SCM_UNSPECIFIED}. If @var{restp} is +@c non-zero, it means that @var{fn} may be called with an arbitrary number +@c of arguments, and that any extra arguments supplied by the caller will +@c be passed to @var{fn} as a list. The @var{restp} argument is exactly +@c like Scheme's @code{(lambda (arg1 arg2 . arglist))} calling convention. +@c +@c For example, the procedure @code{read-line}, which takes optional +@c @var{port} and @var{handle-delim} arguments, would be declared like so: +@c +@c @example +@c SCM scm_read_line (SCM port, SCM handle_delim); +@c gh_make_subr (scm_read_line, 0, 2, 0, "read-line"); +@c @end example +@c +@c The @var{req} argument to @code{gh_make_subr} is 0 to indicate that +@c there are no required arguments, so @code{read-line} may be called +@c without any arguments at all. The @var{opt} argument is 2, to indicate +@c that both the @var{port} and @var{handle_delim} arguments to +@c @code{scm_read_line} are optional, and will be bound to +@c @code{SCM_UNSPECIFIED} if the calling program does not supply them. +@c Because the @var{restp} argument is 0, this function may not be called +@c with more than two arguments. +@c @end deftypefun + +@deftypefun SCM gh_apply (SCM proc, SCM args) +Call the Scheme procedure @var{proc}, with the elements of @var{args} as +arguments. @var{args} must be a proper list. +@end deftypefun + +@deftypefun SCM gh_call0 (SCM proc) +@deftypefunx SCM gh_call1 (SCM proc, SCM arg) +@deftypefunx SCM gh_call2 (SCM proc, SCM arg1, SCM arg2) +@deftypefunx SCM gh_call3 (SCM proc, SCM arg1, SCM arg2, SCM arg3) +Call the Scheme procedure @var{proc} with no arguments +(@code{gh_call0}), one argument (@code{gh_call1}), and so on. You can +get the same effect by wrapping the arguments up into a list, and +calling @code{gh_apply}; Guile provides these functions for convenience. +@end deftypefun + + +@deftypefun SCM gh_catch (SCM key, SCM thunk, SCM handler) +@deftypefunx SCM gh_throw (SCM key, SCM args) +Corresponds to the Scheme @code{catch} and @code{throw} procedures, +which in Guile are provided as primitives. +@end deftypefun + +@c [FIXME: must add the I/O section in gscm.h] + +@deftypefun SCM gh_is_eq (SCM a, SCM b) +@deftypefunx SCM gh_is_eqv (SCM a, SCM b) +@deftypefunx SCM gh_is_equal (SCM a, SCM b) +These correspond to the Scheme @code{eq?}, @code{eqv?} and @code{equal?} +predicates. +@end deftypefun + +@deftypefun int gh_obj_length (SCM @var{obj}) +Returns the raw object length. +@end deftypefun + +@heading Data lookup + +For now I just include Tim Pierce's comments from the @file{gh_data.c} +file; it should be organized into a documentation of the two functions +here. + +@smallexample +/* Data lookups between C and Scheme + + Look up a symbol with a given name, and return the object to which + it is bound. gh_lookup examines the Guile top level, and + gh_module_lookup checks the module namespace specified by the + `vec' argument. + + The return value is the Scheme object to which SNAME is bound, or + SCM_UNDEFINED if SNAME is not bound in the given context. [FIXME: + should this be SCM_UNSPECIFIED? Can a symbol ever legitimately be + bound to SCM_UNDEFINED or SCM_UNSPECIFIED? What is the difference? + -twp] */ +@end smallexample + + +@node Mixing gh and scm APIs +@section Mixing gh and scm APIs + + +@node scm transition summary +@section Transitioning to the scm Interface + +The following table summarizes the available information on how to +transition from the GH to the scm interface. Where transitioning is not +completely straightforward, the table includes a reference to more +detailed documentation in the preceding sections. + +@table @asis +@item Header file +Use @code{#include <libguile.h>} instead of @code{#include +<guile/gh.h>}. + +@item Compiling and Linking +Use @code{guile-config} to pick up the flags required to compile C or +C++ code that uses @code{libguile}, like so + +@smallexample +$(CC) -o prog.o -c prog.c `guile-config compile` +@end smallexample + +If you are using libtool to link your executables, just use +@code{-lguile} in your link command. Libtool will expand this into +the needed linker options automatically. If you are not using +libtool, use the @code{guile-config} program to query the needed +options explicitely. A linker command like + +@smallexample +$(CC) -o prog prog.o `guile-config link` +@end smallexample + +should be all that is needed. To link shared libraries that will be +used as Guile Extensions, use libtool to control both the compilation +and the link stage. + +@item The @code{SCM} type +No change: the scm interface also uses this type to represent an +arbitrary Scheme value. + +@item @code{SCM_BOOL_F} and @code{SCM_BOOL_T} +No change. + +@item @code{SCM_UNSPECIFIED} and @code{SCM_UNDEFINED} +No change. + +@item @code{gh_enter} +Use @code{scm_boot_guile} instead, but note that @code{scm_boot_guile} +has a slightly different calling convention from @code{gh_enter}: +@code{scm_boot_guile}, and the main program function that you specify +for @code{scm_boot_guile} to call, both take an additional @var{closure} +parameter. @ref{Guile Initialization Functions} for more details. + +@item @code{gh_repl} +Use @code{scm_shell} instead. + +@item @code{gh_init} +Use @code{scm_init_guile} instead. + +@item @code{gh_eval_str} +Use @code{scm_c_eval_string} instead. + +@item @code{gh_eval_file} or @code{gh_load} +Use @code{scm_c_primitive_load} instead. + +@item @code{gh_new_procedure} +Use @code{scm_c_define_gsubr} instead, but note that the arguments are +in a different order: for @code{scm_c_define_gsubr} the C function +pointer is the last argument. @ref{A Sample Guile Extension} for an +example. + +@item @code{gh_defer_ints} and @code{gh_allow_ints} +Use @code{SCM_DEFER_INTS} and @code{SCM_ALLOW_INTS} instead. Note that +these macros are used without parentheses, as in @code{SCM_DEFER_INTS;}. + +@item @code{gh_bool2scm} +Use @code{SCM_BOOL} instead. + +@item @code{gh_ulong2scm} +Use @code{scm_ulong2num} instead. + +@item @code{gh_long2scm} +Use @code{scm_long2num} instead. + +@item @code{gh_double2scm} +Use @code{scm_make_real} instead. + +@item @code{gh_char2scm} +Use @code{SCM_MAKE_CHAR} instead. + +@item @code{gh_str2scm} +Use @code{scm_mem2string} instead. + +@item @code{gh_str02scm} +Use @code{scm_makfrom0str} instead. + +@item @code{gh_set_substr} +No direct scm equivalent. [FIXME] + +@item @code{gh_symbol2scm} +Use @code{scm_str2symbol} instead. [FIXME: inconsistent naming, +should be @code{scm_str02symbol}.] + +@item @code{gh_ints2scm} and @code{gh_doubles2scm} +No direct scm equivalent. [FIXME] + +@item @code{gh_chars2byvect} and @code{gh_shorts2svect} +No direct scm equivalent. [FIXME] + +@item @code{gh_longs2ivect} and @code{gh_ulongs2uvect} +No direct scm equivalent. [FIXME] + +@item @code{gh_floats2fvect} and @code{gh_doubles2dvect} +No direct scm equivalent. [FIXME] + +@item @code{gh_scm2bool} +Use @code{SCM_NFALSEP} instead. + +@item @code{gh_scm2int} +Replace @code{gh_scm2int (@var{obj})} by +@example +scm_num2int (@var{obj}, SCM_ARG1, @var{str}) +@end example +where @var{str} is a C string that describes the context of the call. + +@item @code{gh_scm2ulong} +Replace @code{gh_scm2ulong (@var{obj})} by +@example +scm_num2ulong (@var{obj}, SCM_ARG1, @var{str}) +@end example +where @var{str} is a C string that describes the context of the call. + +@item @code{gh_scm2long} +Replace @code{gh_scm2long (@var{obj})} by +@example +scm_num2long (@var{obj}, SCM_ARG1, @var{str}) +@end example +where @var{str} is a C string that describes the context of the call. + +@item @code{gh_scm2double} +Replace @code{gh_scm2double (@var{obj})} by +@example +scm_num2dbl (@var{obj}, @var{str}) +@end example +where @var{str} is a C string that describes the context of the call. + +@item @code{gh_scm2char} +Use the @code{SCM_CHAR} macro instead, but note that @code{SCM_CHAR} +does not check that its argument is actually a character. To check that +a @code{SCM} value is a character before using @code{SCM_CHAR} to +extract the character value, use the @code{SCM_VALIDATE_CHAR} macro. + +@item @code{gh_scm2newstr} +No direct scm equivalent. [FIXME] + +@item @code{gh_get_substr} +No direct scm equivalent. [FIXME] + +@item @code{gh_symbol2newstr} +No direct scm equivalent. [FIXME] + +@item @code{gh_scm2chars} +No direct scm equivalent. [FIXME] + +@item @code{gh_scm2shorts} and @code{gh_scm2longs} +No direct scm equivalent. [FIXME] + +@item @code{gh_scm2floats} and @code{gh_scm2doubles} +No direct scm equivalent. [FIXME] + +@item @code{gh_boolean_p} +Use the @code{SCM_BOOLP} macro instead, or replace @code{gh_boolean_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_boolean_p (@var{obj})) +@end example + +@item @code{gh_symbol_p} +Use the @code{SCM_SYMBOLP} macro instead, or replace @code{gh_symbol_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_symbol_p (@var{obj})) +@end example + +@item @code{gh_char_p} +Use the @code{SCM_CHARP} macro instead, or replace @code{gh_char_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_char_p (@var{obj})) +@end example + +@item @code{gh_vector_p} +Use the @code{SCM_VECTORP} macro instead, or replace @code{gh_vector_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_vector_p (@var{obj})) +@end example + +@item @code{gh_pair_p} +Use the @code{SCM_CONSP} macro instead, or replace @code{gh_pair_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_pair_p (@var{obj})) +@end example + +@item @code{gh_number_p} +Use the @code{SCM_NUMBERP} macro instead, or replace @code{gh_number_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_number_p (@var{obj})) +@end example + +@item @code{gh_string_p} +Use the @code{SCM_STRINGP} macro instead, or replace @code{gh_string_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_string_p (@var{obj})) +@end example + +@item @code{gh_procedure_p} +Replace @code{gh_procedure_p (@var{obj})} by +@example +SCM_NFALSEP (scm_procedure_p (@var{obj})) +@end example + +@item @code{gh_list_p} +Replace @code{gh_list_p (@var{obj})} by +@example +SCM_NFALSEP (scm_list_p (@var{obj})) +@end example + +@item @code{gh_inexact_p} +Use the @code{SCM_INEXACTP} macro instead, or replace @code{gh_inexact_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_inexact_p (@var{obj})) +@end example + +@item @code{gh_exact_p} +Replace @code{gh_exact_p (@var{obj})} by +@example +SCM_NFALSEP (scm_exact_p (@var{obj})) +@end example + +@item @code{gh_eq_p} +Use the @code{SCM_EQ_P} macro instead, or replace @code{gh_eq_p +(@var{x}, @var{y})} by +@example +SCM_NFALSEP (scm_eq_p (@var{x}, @var{y})) +@end example + +@item @code{gh_eqv_p} +Replace @code{gh_eqv_p (@var{x}, @var{y})} by +@example +SCM_NFALSEP (scm_eqv_p (@var{x}, @var{y})) +@end example + +@item @code{gh_equal_p} +Replace @code{gh_equal_p (@var{x}, @var{y})} by +@example +SCM_NFALSEP (scm_equal_p (@var{x}, @var{y})) +@end example + +@item @code{gh_string_equal_p} +Replace @code{gh_string_equal_p (@var{x}, @var{y})} by +@example +SCM_NFALSEP (scm_string_equal_p (@var{x}, @var{y})) +@end example + +@item @code{gh_null_p} +Use the @code{SCM_NULLP} macro instead, or replace @code{gh_null_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_null_p (@var{obj})) +@end example + +@item @code{gh_cons} +Use @code{scm_cons} instead. + +@item @code{gh_car} and @code{gh_cdr} +Use the @code{SCM_CAR} and @code{SCM_CDR} macros instead. + +@item @code{gh_cxxr} and @code{gh_cxxxr} +(Where each x is either @samp{a} or @samp{d}.) Use the corresponding +@code{SCM_CXXR} or @code{SCM_CXXXR} macro instead. + +@item @code{gh_set_car_x} and @code{gh_set_cdr_x} +Use @code{scm_set_car_x} and @code{scm_set_cdr_x} instead. + +@item @code{gh_list} +Use @code{scm_listify} instead. + +@item @code{gh_length} +Replace @code{gh_length (@var{lst})} by +@example +scm_num2ulong (scm_length (@var{lst}), SCM_ARG1, @var{str}) +@end example +where @var{str} is a C string that describes the context of the call. + +@item @code{gh_append} +Use @code{scm_append} instead. + +@item @code{gh_append2}, @code{gh_append3}, @code{gh_append4} +Replace @code{gh_append@var{N} (@var{l1}, @dots{}, @var{lN})} by +@example +scm_append (scm_listify (@var{l1}, @dots{}, @var{lN}, SCM_UNDEFINED)) +@end example + +@item @code{gh_reverse} +Use @code{scm_reverse} instead. + +@item @code{gh_list_tail} and @code{gh_list_ref} +Use @code{scm_list_tail} and @code{scm_list_ref} instead. + +@item @code{gh_memq}, @code{gh_memv} and @code{gh_member} +Use @code{scm_memq}, @code{scm_memv} and @code{scm_member} instead. + +@item @code{gh_assq}, @code{gh_assv} and @code{gh_assoc} +Use @code{scm_assq}, @code{scm_assv} and @code{scm_assoc} instead. + +@item @code{gh_make_vector} +Use @code{scm_make_vector} instead. + +@item @code{gh_vector} or @code{gh_list_to_vector} +Use @code{scm_vector} instead. + +@item @code{gh_vector_ref} and @code{gh_vector_set_x} +Use @code{scm_vector_ref} and @code{scm_vector_set_x} instead. + +@item @code{gh_vector_length} +Use the @code{SCM_VECTOR_LENGTH} macro instead. + +@item @code{gh_apply} +Use @code{scm_apply} instead, but note that @code{scm_apply} takes an +additional third argument that you should set to @code{SCM_EOL}. + +@end table diff --git a/doc/guile.texi b/doc/ref/guile.texi index b4cfad73a..1ba439931 100644 --- a/doc/guile.texi +++ b/doc/ref/guile.texi @@ -80,7 +80,7 @@ by the Free Software Foundation. @sp 10 @comment The title is printed in a large font. @title Guile Reference Manual -@subtitle $Id: guile.texi,v 1.12 2001-06-29 21:43:17 mgrabmue Exp $ +@subtitle $Id: guile.texi,v 1.1 2001-08-24 09:40:29 ossau Exp $ @subtitle For use with Guile @value{VERSION} @include AUTHORS diff --git a/doc/ref/indices.texi b/doc/ref/indices.texi new file mode 100644 index 000000000..a35592e90 --- /dev/null +++ b/doc/ref/indices.texi @@ -0,0 +1,54 @@ +@node Concept Index +@unnumbered Concept Index + +This index contains concepts, keywords and non-Schemey names for several +features, to make it easier to locate the desired sections. + +@printindex cp + + +@page +@node Procedure Index +@unnumbered Procedure Index + +@c FIXME::martin: Review me! + +This is an alphabetical list of all the procedures and macros in Guile. + +When looking for a particular procedure, please look under its Scheme +name as well as under its C name. The C name can be constructed from +the Scheme names by a simple transformation described in the section +@xref{Transforming Scheme name to C name}. + +@printindex fn + + +@page +@node Variable Index +@unnumbered Variable Index + +@c FIXME::martin: Review me! + +This is an alphabetical list of all the important variables and +constants in Guile. + +When looking for a particular variable or constant, please look under +its Scheme name as well as under its C name. The C name can be +constructed from the Scheme names by a simple transformation described +in the section @xref{Transforming Scheme name to C name}. + +@printindex vr + + +@page +@c Spell out this node fully, because it is the last real node +@c in the top-level menu. Leaving off the pointers here causes +@c spurious makeinfo errors. +@node Type Index +@unnumbered Type Index + +This is an alphabetical list of all the important data types defined in +the Guile Programmers Manual. + +@printindex tp + diff --git a/doc/intro.texi b/doc/ref/intro.texi index 8e859c825..28e30d06b 100644 --- a/doc/intro.texi +++ b/doc/ref/intro.texi @@ -1,4 +1,4 @@ -@c $Id: intro.texi,v 1.12 2001-06-14 17:36:41 mvo Exp $ +@c $Id: intro.texi,v 1.1 2001-08-24 09:40:29 ossau Exp $ @page @node What is Guile? diff --git a/doc/ref/misc-modules.texi b/doc/ref/misc-modules.texi new file mode 100644 index 000000000..30f821937 --- /dev/null +++ b/doc/ref/misc-modules.texi @@ -0,0 +1,291 @@ +@page +@node Pretty Printing +@chapter Pretty Printing + +@c FIXME::martin: Review me! + +@cindex pretty printing +The module @code{(ice-9 pretty-print)} provides the procedure +@code{pretty-print}, which provides nicely formatted output of Scheme +objects. This is especially useful for deeply nested or complex data +structures, such as lists and vectors. + +The module is loaded by simply saying. + +@lisp +(use-modules (ice-9 pretty-print)) +@end lisp + +This makes the procedure @code{pretty-print} available. As an example +how @code{pretty-print} will format the output, see the following: + +@lisp +(pretty-print '(define (foo) (lambda (x) +(cond ((zero? x) #t) ((negative? x) -x) (else (if (= x 1) 2 (* x x x))))))) +@print{} +(define (foo) + (lambda (x) + (cond ((zero? x) #t) + ((negative? x) -x) + (else (if (= x 1) 2 (* x x x)))))) +@end lisp + +@deffn procedure pretty-print obj [port] +Print the textual representation of the Scheme object @var{obj} to +@var{port}. @var{port} defaults to the current output port, if not +given. +@end deffn + +Beware: Since @code{pretty-print} uses it's own write procedure, it's +output will not be the same as for example the output of @code{write}. +Consider the following example. + +@lisp +(write (lambda (x) x)) +@print{} +#<procedure #f (x)> + +(pretty-print (lambda (x) x)) +@print{} +#[procedure] +@end lisp + +The reason is that @code{pretty-print} does not know as much about +Guile's object types as the builtin procedures. This is particularly +important for smobs, for which a write procedure can be defined and be +used by @code{write}, but not by @code{pretty-print}. + +@page +@node Formatted Output +@chapter Formatted Output + +@c FIXME::martin: Review me! + +@cindex format +@cindex formatted output +Outputting messages or other texts which are composed of literal +strings, variable contents, newlines and other formatting can be +cumbersome, when only the standard procedures like @code{display}, +@code{write} and @code{newline} are available. Additionally, one +often wants to collect the output in strings. With the standard +routines, the user is required to set up a string port, add this port +as a parameter to the output procedure calls and then retrieve the +resulting string from the string port. + +The @code{format} procedure, to be found in module @code{(ice-9 +format)}, can do all this, and even more. If you are a C programmer, +you can think of this procedure as Guile's @code{fprintf}. + +@deffn procedure format destination format-string args @dots{} +The first parameter is the @var{destination}, it determines where the +output of @code{format} will go. + +@table @asis +@item @code{#t} +Send the formatted output to the current output port and return +@code{#t}. + +@item @code{#f} +Return the formatted output as a string. + +@item Any number value +Send the formatted output to the current error port and return +@code{#t}. + +@item A valid output port +Send the formatted output to the port @var{destination} and return +@code{#t}. +@end table + +The second parameter is the format string. It has a similar function +to the format string in calls to @code{printf} or @code{fprintf} in C. +It is output to the specified destination, but all escape sequences +are replaced by the results of formatting the corresponding sequence. + +Note that escape sequences are marked with the character @code{~} +(tilde), and not with a @code{%} (percent sign), as in C. + +The escape sequences in the following table are supported. When there +appears ``corresponding @var{arg}', that means any of the additional +arguments, after dropping all arguments which have been used up by +escape sequences which have been processed earlier. Some of the +format characters (the characters following the tilde) can be prefixed +by @code{:}, @code{@@}, or @code{:@@}, to modify the behaviour of the +format character. How the modified behaviour differs from the default +behaviour is described for every character in the table where +appropriate. + +@table @code +@item ~~ +Output a single @code{~} (tilde) character. + +@item ~% +Output a newline character, thus advancing to the next output line. + +@item ~& +Start a new line, that is, output a newline character if not already +at the statr of a line. + +@item ~_ +Output a single space character. + +@item ~/ +Output a single tabulator character. + +@item ~| +Output a page separator (formfeed) character. + +@item ~t +Advance to the next tabulator position. + +@item ~y +Pretty-print the correspinding @var{arg}. + +@item ~a +Output the corresponding @var{arg} like @code{display}. + +@item ~s +Output the corresponding @var{arg} like @code{write}. + +@item ~d +Output the corresponding @var{arg} as a decimal number. + +@item ~x +Output the corresponding @var{arg} as a hexadecimal number. + +@item ~o +Output the corresponding @var{arg} as an octal number. + +@item ~b +Output the corresponding @var{arg} as a binary number. + +@item ~r +Output the corresponding @var{arg} as a number word, e.g. 10 prints as +@code{ten}. If prefixed with @code{:}, @code{tenth} is printed, if +prefixed with @code{:@@}, roman numbers are printed. + +@item ~f +Output the corresponding @var{arg} as a fixed format floating point +number, such as @code{1.34}. + +@item ~e +Output the corresponding @var{arg} in exponential notation, such as +@code{1.34E+0}. + +@item ~g +%% FIXME::martin: There must be a difference. Does anybody know? +Like @code{~f}. + +@item ~$ +Like @code{~f}, but only with two digits after the decimal point. + +@item ~i +Output the corresponding @var{arg} as a complex number. + +@item ~c +Output the corresponding @var{arg} as a character. If prefixed with +@code{@@}, it is printed like with @code{write}. If prefixed with +@code{:}, control characters are treated specially, for example +@code{#\newline} will be printed as @code{^J}. + +@item ~p +``Plural''. If the corresponding @var{arg} is 1, nothing is printed +(or @code{y} if prefixed with @code{@@} or @code{:@@}), otherwise +@code{s} is printed (or @code{ies} if prefixed with @code{@@} or +@code{:@@}). + +@item ~?, ~k +Take the corresponding argument as a format string, and the following +argument as a list of values. Then format the values with respect to +the format string. + +@item ~! +Flush the output to the output port. + +@item ~#\newline (tilde-newline) +@c FIXME::martin: I don't understand this from the source. +Continuation lines. + +@item ~* +Argument jumping. Navigate in the argument list as specified by the +corresponding argument. If prefixed with @code{:}, jump backwards in +the argument list, if prefixed by @code{:@@}, jump to the parameter +with the absolute index, otherwise jump forward in the argument list. + +@item ~( +Case conversion begin. If prefixed by @code{:}, the following output +string will be capitalized, if prefixed by @code{@@}, the first +character will be capitalized, if prefixed by @code{:@@} it will be +upcased and otherwise it will be downcased. Conversion stops when the +``Case conversion end'' @code{~)}sequence is encountered. + +@item ~) +Case conversion end. Stop any case conversion currently in effect. + +@item ~[ +@c FIXME::martin: I don't understand this from the source. +Conditional begin. + +@item ~; +@c FIXME::martin: I don't understand this from the source. +Conditional separator. + +@item ~] +@c FIXME::martin: I don't understand this from the source. +Conditional end. + +@item ~@{ +@c FIXME::martin: I don't understand this from the source. +Iteration begin. + +@item ~@} +@c FIXME::martin: I don't understand this from the source. +Iteration end. + +@item ~^ +@c FIXME::martin: I don't understand this from the source. +Up and out. + +@item ~' +@c FIXME::martin: I don't understand this from the source. +Character parameter. + +@item ~0 @dots{} ~9, ~-, ~+ +@c FIXME::martin: I don't understand this from the source. +Numeric parameter. + +@item ~v +@c FIXME::martin: I don't understand this from the source. +Variable parameter from next argument. + +@item ~# +Parameter is number of remaining args. The number of the remaining +arguments is prepended to the list of unprocessed arguments. + +@item ~, +@c FIXME::martin: I don't understand this from the source. +Parameter separators. + +@item ~q +Inquiry message. Insert a copyright message into the output. +@end table + +If any type conversions should fail (for example when using an escape +sequence for number output, but the argument is a string), an error +will be signalled. +@end deffn + +You may have noticed that Guile contains a @code{format} procedure +even when the module @code{(ice-9 format)} is not loaded. The default +@code{format} procedure does not support all escape sequences +documented in this chapter, and will signal an error if you try to use +one of them. The reason for providing two versions of @code{format} +is that the full-featured module is fairly large and requires some +time to get loaded. So the Guile maintainers decided not to load the +large version of @code{format} by default, so that the start-up time +of the interpreter is not unnecessarily increased. + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/new-docstrings.texi b/doc/ref/new-docstrings.texi new file mode 100644 index 000000000..8bce646e6 --- /dev/null +++ b/doc/ref/new-docstrings.texi @@ -0,0 +1,532 @@ + +@c module (guile) + +@deffn primitive environment? obj +Return @code{#t} if @var{obj} is an environment, or @code{#f} +otherwise. +@end deffn + +@deffn primitive environment-bound? env sym +Return @code{#t} if @var{sym} is bound in @var{env}, or +@code{#f} otherwise. +@end deffn + +@deffn primitive environment-ref env sym +Return the value of the location bound to @var{sym} in +@var{env}. If @var{sym} is unbound in @var{env}, signal an +@code{environment:unbound} error. +@end deffn + +@deffn primitive environment-fold env proc init +Iterate over all the bindings in @var{env}, accumulating some +value. +For each binding in @var{env}, apply @var{proc} to the symbol +bound, its value, and the result from the previous application +of @var{proc}. +Use @var{init} as @var{proc}'s third argument the first time +@var{proc} is applied. +If @var{env} contains no bindings, this function simply returns +@var{init}. +If @var{env} binds the symbol sym1 to the value val1, sym2 to +val2, and so on, then this procedure computes: +@lisp + (proc sym1 val1 + (proc sym2 val2 + ... + (proc symn valn + init))) +@end lisp +Each binding in @var{env} will be processed exactly once. +@code{environment-fold} makes no guarantees about the order in +which the bindings are processed. +Here is a function which, given an environment, constructs an +association list representing that environment's bindings, +using environment-fold: +@lisp + (define (environment->alist env) + (environment-fold env + (lambda (sym val tail) + (cons (cons sym val) tail)) + '())) +@end lisp +@end deffn + +@deffn primitive environment-define env sym val +Bind @var{sym} to a new location containing @var{val} in +@var{env}. If @var{sym} is already bound to another location +in @var{env} and the binding is mutable, that binding is +replaced. The new binding and location are both mutable. The +return value is unspecified. +If @var{sym} is already bound in @var{env}, and the binding is +immutable, signal an @code{environment:immutable-binding} error. +@end deffn + +@deffn primitive environment-undefine env sym +Remove any binding for @var{sym} from @var{env}. If @var{sym} +is unbound in @var{env}, do nothing. The return value is +unspecified. +If @var{sym} is already bound in @var{env}, and the binding is +immutable, signal an @code{environment:immutable-binding} error. +@end deffn + +@deffn primitive environment-set! env sym val +If @var{env} binds @var{sym} to some location, change that +location's value to @var{val}. The return value is +unspecified. +If @var{sym} is not bound in @var{env}, signal an +@code{environment:unbound} error. If @var{env} binds @var{sym} +to an immutable location, signal an +@code{environment:immutable-location} error. +@end deffn + +@deffn primitive environment-cell env sym for_write +Return the value cell which @var{env} binds to @var{sym}, or +@code{#f} if the binding does not live in a value cell. +The argument @var{for-write} indicates whether the caller +intends to modify the variable's value by mutating the value +cell. If the variable is immutable, then +@code{environment-cell} signals an +@code{environment:immutable-location} error. +If @var{sym} is unbound in @var{env}, signal an +@code{environment:unbound} error. +If you use this function, you should consider using +@code{environment-observe}, to be notified when @var{sym} gets +re-bound to a new value cell, or becomes undefined. +@end deffn + +@deffn primitive environment-observe env proc +Whenever @var{env}'s bindings change, apply @var{proc} to +@var{env}. +This function returns an object, token, which you can pass to +@code{environment-unobserve} to remove @var{proc} from the set +of procedures observing @var{env}. The type and value of +token is unspecified. +@end deffn + +@deffn primitive environment-observe-weak env proc +This function is the same as environment-observe, except that +the reference @var{env} retains to @var{proc} is a weak +reference. This means that, if there are no other live, +non-weak references to @var{proc}, it will be +garbage-collected, and dropped from @var{env}'s +list of observing procedures. +@end deffn + +@deffn primitive environment-unobserve token +Cancel the observation request which returned the value +@var{token}. The return value is unspecified. +If a call @code{(environment-observe env proc)} returns +@var{token}, then the call @code{(environment-unobserve token)} +will cause @var{proc} to no longer be called when @var{env}'s +bindings change. +@end deffn + +@deffn primitive make-leaf-environment +Create a new leaf environment, containing no bindings. +All bindings and locations created in the new environment +will be mutable. +@end deffn + +@deffn primitive leaf-environment? object +Return @code{#t} if object is a leaf environment, or @code{#f} +otherwise. +@end deffn + +@deffn primitive make-eval-environment local imported +Return a new environment object eval whose bindings are the +union of the bindings in the environments @var{local} and +@var{imported}, with bindings from @var{local} taking +precedence. Definitions made in eval are placed in @var{local}. +Applying @code{environment-define} or +@code{environment-undefine} to eval has the same effect as +applying the procedure to @var{local}. +Note that eval incorporates @var{local} and @var{imported} by +reference: +If, after creating eval, the program changes the bindings of +@var{local} or @var{imported}, those changes will be visible +in eval. +Since most Scheme evaluation takes place in eval environments, +they transparently cache the bindings received from @var{local} +and @var{imported}. Thus, the first time the program looks up +a symbol in eval, eval may make calls to @var{local} or +@var{imported} to find their bindings, but subsequent +references to that symbol will be as fast as references to +bindings in finite environments. +In typical use, @var{local} will be a finite environment, and +@var{imported} will be an import environment +@end deffn + +@deffn primitive eval-environment? object +Return @code{#t} if object is an eval environment, or @code{#f} +otherwise. +@end deffn + +@deffn primitive eval-environment-local env +Return the local environment of eval environment @var{env}. +@end deffn + +@deffn primitive eval-environment-set-local! env local +Change @var{env}'s local environment to @var{local}. +@end deffn + +@deffn primitive eval-environment-imported env +Return the imported environment of eval environment @var{env}. +@end deffn + +@deffn primitive eval-environment-set-imported! env imported +Change @var{env}'s imported environment to @var{imported}. +@end deffn + +@deffn primitive make-import-environment imports conflict_proc +Return a new environment @var{imp} whose bindings are the union +of the bindings from the environments in @var{imports}; +@var{imports} must be a list of environments. That is, +@var{imp} binds a symbol to a location when some element of +@var{imports} does. +If two different elements of @var{imports} have a binding for +the same symbol, the @var{conflict-proc} is called with the +following parameters: the import environment, the symbol and +the list of the imported environments that bind the symbol. +If the @var{conflict-proc} returns an environment @var{env}, +the conflict is considered as resolved and the binding from +@var{env} is used. If the @var{conflict-proc} returns some +non-environment object, the conflict is considered unresolved +and the symbol is treated as unspecified in the import +environment. +The checking for conflicts may be performed lazily, i. e. at +the moment when a value or binding for a certain symbol is +requested instead of the moment when the environment is +created or the bindings of the imports change. +All bindings in @var{imp} are immutable. If you apply +@code{environment-define} or @code{environment-undefine} to +@var{imp}, Guile will signal an + @code{environment:immutable-binding} error. However, +notice that the set of bindings in @var{imp} may still change, +if one of its imported environments changes. +@end deffn + +@deffn primitive import-environment? object +Return @code{#t} if object is an import environment, or +@code{#f} otherwise. +@end deffn + +@deffn primitive import-environment-imports env +Return the list of environments imported by the import +environment @var{env}. +@end deffn + +@deffn primitive import-environment-set-imports! env imports +Change @var{env}'s list of imported environments to +@var{imports}, and check for conflicts. +@end deffn + +@deffn primitive make-export-environment private signature +Return a new environment @var{exp} containing only those +bindings in private whose symbols are present in +@var{signature}. The @var{private} argument must be an +environment. + +The environment @var{exp} binds symbol to location when +@var{env} does, and symbol is exported by @var{signature}. + +@var{signature} is a list specifying which of the bindings in +@var{private} should be visible in @var{exp}. Each element of +@var{signature} should be a list of the form: + (symbol attribute ...) +where each attribute is one of the following: +@table @asis +@item the symbol @code{mutable-location} + @var{exp} should treat the + location bound to symbol as mutable. That is, @var{exp} + will pass calls to @code{environment-set!} or + @code{environment-cell} directly through to private. +@item the symbol @code{immutable-location} + @var{exp} should treat + the location bound to symbol as immutable. If the program + applies @code{environment-set!} to @var{exp} and symbol, or + calls @code{environment-cell} to obtain a writable value + cell, @code{environment-set!} will signal an + @code{environment:immutable-location} error. Note that, even + if an export environment treats a location as immutable, the + underlying environment may treat it as mutable, so its + value may change. +@end table +It is an error for an element of signature to specify both +@code{mutable-location} and @code{immutable-location}. If +neither is specified, @code{immutable-location} is assumed. + +As a special case, if an element of signature is a lone +symbol @var{sym}, it is equivalent to an element of the form +@code{(sym)}. + +All bindings in @var{exp} are immutable. If you apply +@code{environment-define} or @code{environment-undefine} to +@var{exp}, Guile will signal an +@code{environment:immutable-binding} error. However, +notice that the set of bindings in @var{exp} may still change, +if the bindings in private change. +@end deffn + +@deffn primitive export-environment? object +Return @code{#t} if object is an export environment, or +@code{#f} otherwise. +@end deffn + +@deffn primitive export-environment-private env +Return the private environment of export environment @var{env}. +@end deffn + +@deffn primitive export-environment-set-private! env private +Change the private environment of export environment @var{env}. +@end deffn + +@deffn primitive export-environment-signature env +Return the signature of export environment @var{env}. +@end deffn + +@deffn primitive export-environment-set-signature! env signature +Change the signature of export environment @var{env}. +@end deffn + +@deffn primitive %compute-slots class +Return a list consisting of the names of all slots belonging to +class @var{class}, i. e. the slots of @var{class} and of all of +its superclasses. +@end deffn + +@deffn primitive get-keyword key l default_value +Determine an associated value for the keyword @var{key} from +the list @var{l}. The list @var{l} has to consist of an even +number of elements, where, starting with the first, every +second element is a keyword, followed by its associated value. +If @var{l} does not hold a value for @var{key}, the value +@var{default_value} is returned. +@end deffn + +@deffn primitive slot-ref-using-class class obj slot_name +@end deffn + +@deffn primitive slot-set-using-class! class obj slot_name value +@end deffn + +@deffn primitive class-of x +Return the class of @var{x}. +@end deffn + +@deffn primitive %goops-loaded +Announce that GOOPS is loaded and perform initialization +on the C level which depends on the loaded GOOPS modules. +@end deffn + +@deffn primitive %method-more-specific? m1 m2 targs +@end deffn + +@deffn primitive find-method . l +@end deffn + +@deffn primitive primitive-generic-generic subr +@end deffn + +@deffn primitive enable-primitive-generic! . subrs +@end deffn + +@deffn primitive generic-capability? proc +@end deffn + +@deffn primitive %invalidate-method-cache! gf +@end deffn + +@deffn primitive %invalidate-class class +@end deffn + +@deffn primitive %modify-class old new +@end deffn + +@deffn primitive %modify-instance old new +@end deffn + +@deffn primitive %set-object-setter! obj setter +@end deffn + +@deffn primitive %allocate-instance class initargs +Create a new instance of class @var{class} and initialize it +from the arguments @var{initargs}. +@end deffn + +@deffn primitive slot-exists? obj slot_name +Return @code{#t} if @var{obj} has a slot named @var{slot_name}. +@end deffn + +@deffn primitive slot-bound? obj slot_name +Return @code{#t} if the slot named @var{slot_name} of @var{obj} +is bound. +@end deffn + +@deffn primitive slot-set! obj slot_name value +Set the slot named @var{slot_name} of @var{obj} to @var{value}. +@end deffn + +@deffn primitive slot-exists-using-class? class obj slot_name +@end deffn + +@deffn primitive slot-bound-using-class? class obj slot_name +@end deffn + +@deffn primitive %fast-slot-set! obj index value +Set the slot with index @var{index} in @var{obj} to +@var{value}. +@end deffn + +@deffn primitive %fast-slot-ref obj index +Return the slot value with index @var{index} from @var{obj}. +@end deffn + +@deffn primitive @@assert-bound-ref obj index +Like @code{assert-bound}, but use @var{index} for accessing +the value from @var{obj}. +@end deffn + +@deffn primitive assert-bound value obj +Return @var{value} if it is bound, and invoke the +@var{slot-unbound} method of @var{obj} if it is not. +@end deffn + +@deffn primitive unbound? obj +Return @code{#t} if @var{obj} is unbound. +@end deffn + +@deffn primitive make-unbound +Return the unbound value. +@end deffn + +@deffn primitive accessor-method-slot-definition obj +Return the slot definition of the accessor @var{obj}. +@end deffn + +@deffn primitive method-procedure obj +Return the procedure of the method @var{obj}. +@end deffn + +@deffn primitive method-specializers obj +Return specializers of the method @var{obj}. +@end deffn + +@deffn primitive method-generic-function obj +Return the generic function fot the method @var{obj}. +@end deffn + +@deffn primitive generic-function-methods obj +Return the methods of the generic function @var{obj}. +@end deffn + +@deffn primitive generic-function-name obj +Return the name of the generic function @var{obj}. +@end deffn + +@deffn primitive class-environment obj +Return the environment of the class @var{obj}. +@end deffn + +@deffn primitive class-slots obj +Return the slot list of the class @var{obj}. +@end deffn + +@deffn primitive class-precedence-list obj +Return the class precedence list of the class @var{obj}. +@end deffn + +@deffn primitive class-direct-methods obj +Return the direct methods of the class @var{obj} +@end deffn + +@deffn primitive class-direct-subclasses obj +Return the direct subclasses of the class @var{obj}. +@end deffn + +@deffn primitive class-direct-slots obj +Return the direct slots of the class @var{obj}. +@end deffn + +@deffn primitive class-direct-supers obj +Return the direct superclasses of the class @var{obj}. +@end deffn + +@deffn primitive class-name obj +Return the class name of @var{obj}. +@end deffn + +@deffn primitive instance? obj +Return @code{#t} if @var{obj} is an instance. +@end deffn + +@deffn primitive %inherit-magic! class dsupers +@end deffn + +@deffn primitive %prep-layout! class +@end deffn + +@deffn primitive %initialize-object obj initargs +Initialize the object @var{obj} with the given arguments +@var{initargs}. +@end deffn + +@deffn primitive make . args +Make a new object. @var{args} must contain the class and +all necessary initialization information. +@end deffn + +@deffn primitive slot-ref obj slot_name +Return the value from @var{obj}'s slot with the name +@var{slot_name}. +@end deffn + +@deffn primitive builtin-bindings +Create and return a copy of the global symbol table, removing all +unbound symbols. +@end deffn + +@deffn primitive %tag-body body +Internal GOOPS magic---don't use this function! +@end deffn + +@deffn primitive list* +scm_cons_star +@end deffn + +@deffn primitive set-current-module module +Set the current module to @var{module} and return +the previous current module. +@end deffn + +@deffn primitive current-module +Return the current module. +@end deffn + +@deffn primitive c-clear-registered-modules +Destroy the list of modules registered with the current Guile process. +The return value is unspecified. @strong{Warning:} this function does +not actually unlink or deallocate these modules, but only destroys the +records of which modules have been loaded. It should therefore be used +only by module bookkeeping operations. +@end deffn + +@deffn primitive c-registered-modules +Return a list of the object code modules that have been imported into +the current Guile process. Each element of the list is a pair whose +car is the name of the module, and whose cdr is the function handle +for that module's initializer function. The name is the string that +has been passed to scm_register_module_xxx. +@end deffn + +@deffn primitive include-deprecated-features +Return @code{#t} iff deprecated features should be included +in public interfaces. +@end deffn + +@deffn primitive issue-deprecation-warning . msgs +Output @var{msgs} to @code{(current-error-port)} when this +is the first call to @code{issue-deprecation-warning} with +this specific @var{msg}. Do nothing otherwise. +The argument @var{msgs} should be a list of strings; +they are printed in turn, each one followed by a newline. +@end deffn diff --git a/doc/ref/posix.texi b/doc/ref/posix.texi new file mode 100644 index 000000000..4d4473422 --- /dev/null +++ b/doc/ref/posix.texi @@ -0,0 +1,2328 @@ +@node POSIX +@chapter POSIX System Calls and Networking + +@menu +* Conventions:: Conventions employed by the POSIX interface. +* Ports and File Descriptors:: Scheme ``ports'' and Unix file descriptors + have different representations. +* File System:: stat, chown, chmod, etc. +* User Information:: Retrieving a user's GECOS (/etc/passwd) entry. +* Time:: gettimeofday, localtime, strftime, etc. +* Runtime Environment:: Accessing and modifying Guile's environment. +* Processes:: getuid, getpid, etc. +* Signals:: sigaction, kill, pause, alarm, setitimer, etc. +* Terminals and Ptys:: ttyname, tcsetpgrp, etc. +* Pipes:: Communicating data between processes. +* Networking:: gethostbyaddr, getnetent, socket, bind, listen. +* System Identification:: Obtaining information about the system. +* Locales:: setlocale, etc. +* Encryption:: +@end menu + +@node Conventions +@section POSIX Interface Conventions + +These interfaces provide access to operating system facilities. +They provide a simple wrapping around the underlying C interfaces +to make usage from Scheme more convenient. They are also used +to implement the Guile port of @ref{The Scheme shell (scsh)}. + +Generally there is a single procedure for each corresponding Unix +facility. There are some exceptions, such as procedures implemented for +speed and convenience in Scheme with no primitive Unix equivalent, +e.g., @code{copy-file}. + +The interfaces are intended as far as possible to be portable across +different versions of Unix. In some cases procedures which can't be +implemented on particular systems may become no-ops, or perform limited +actions. In other cases they may throw errors. + +General naming conventions are as follows: + +@itemize @bullet +@item +The Scheme name is often identical to the name of the underlying Unix +facility. +@item +Underscores in Unix procedure names are converted to hyphens. +@item +Procedures which destructively modify Scheme data have exclaimation +marks appended, e.g., @code{recv!}. +@item +Predicates (returning only @code{#t} or @code{#f}) have question marks +appended, e.g., @code{access?}. +@item +Some names are changed to avoid conflict with dissimilar interfaces +defined by scsh, e.g., @code{primitive-fork}. +@item +Unix preprocessor names such as @code{EPERM} or @code{R_OK} are converted +to Scheme variables of the same name (underscores are not replaced +with hyphens). +@end itemize + +Unexpected conditions are generally handled by raising exceptions. +There are a few procedures which return a special value if they don't +succeed, e.g., @code{getenv} returns @code{#f} if it the requested +string is not found in the environment. These cases are noted in +the documentation. + +For ways to deal with exceptions, @ref{Exceptions}. + +Errors which the C-library would report by returning a NULL pointer or +through some other means are reported by raising a @code{system-error} +exception. The value of the Unix @code{errno} variable is available +in the data passed by the exception. + +It can be extracted with the function @code{system-error-errno}: + +@example +(catch + 'system-error + (lambda () + (mkdir "/this-ought-to-fail-if-I'm-not-root")) + (lambda stuff + (let ((errno (system-error-errno stuff))) + (cond + ((= errno EACCES) + (display "You're not allowed to do that.")) + ((= errno EEXIST) + (display "Already exists.")) + (#t + (display (strerror errno)))) + (newline)))) +@end example + +@node Ports and File Descriptors +@section Ports and File Descriptors + +Conventions generally follow those of scsh, @ref{The Scheme shell (scsh)}. + +File ports are implemented using low-level operating system I/O +facilities, with optional buffering to improve efficiency +@pxref{File Ports} + +Note that some procedures (e.g., @code{recv!}) will accept ports as +arguments, but will actually operate directly on the file descriptor +underlying the port. Any port buffering is ignored, including the +buffer which implements @code{peek-char} and @code{unread-char}. + +The @code{force-output} and @code{drain-input} procedures can be used +to clear the buffers. + +Each open file port has an associated operating system file descriptor. +File descriptors are generally not useful in Scheme programs; however +they may be needed when interfacing with foreign code and the Unix +environment. + +A file descriptor can be extracted from a port and a new port can be +created from a file descriptor. However a file descriptor is just an +integer and the garbage collector doesn't recognise it as a reference +to the port. If all other references to the port were dropped, then +it's likely that the garbage collector would free the port, with the +side-effect of closing the file descriptor prematurely. + +To assist the programmer in avoiding this problem, each port has an +associated "revealed count" which can be used to keep track of how many +times the underlying file descriptor has been stored in other places. +If a port's revealed count is greater than zero, the file descriptor +will not be closed when the port is gabage collected. A programmer +can therefore ensure that the revealed count will be greater than +zero if the file descriptor is needed elsewhere. + +For the simple case where a file descriptor is "imported" once to become +a port, it does not matter if the file descriptor is closed when the +port is garbage collected. There is no need to maintain a revealed +count. Likewise when "exporting" a file descriptor to the external +environment, setting the revealed count is not required provided the +port is kept open (i.e., is pointed to by a live Scheme binding) while +the file descriptor is in use. + +To correspond with traditional Unix behaviour, the three file +descriptors (0, 1 and 2) are automatically imported when a program +starts up and assigned to the initial values of the current input, +output and error ports. The revealed count for each is initially set to +one, so that dropping references to one of these ports will not result +in its garbage collection: it could be retrieved with fdopen or +fdes->ports. + +@deffn primitive port-revealed port +Return the revealed count for @var{port}. +@end deffn + +@deffn primitive set-port-revealed! port rcount +Sets the revealed count for a port to a given value. +The return value is unspecified. +@end deffn + +@deffn primitive fileno port +Return the integer file descriptor underlying @var{port}. Does +not change its revealed count. +@end deffn + +@deffn procedure port->fdes port +Returns the integer file descriptor underlying @var{port}. As a +side effect the revealed count of @var{port} is incremented. +@end deffn + +@deffn primitive fdopen fdes modes +Return a new port based on the file descriptor @var{fdes}. +Modes are given by the string @var{modes}. The revealed count +of the port is initialized to zero. The modes string is the +same as that accepted by @ref{File Ports, open-file}. +@end deffn + +@deffn primitive fdes->ports fd +Return a list of existing ports which have @var{fdes} as an +underlying file descriptor, without changing their revealed +counts. +@end deffn + +@deffn procedure fdes->inport fdes +Returns an existing input port which has @var{fdes} as its underlying file +descriptor, if one exists, and increments its revealed count. +Otherwise, returns a new input port with a revealed count of 1. +@end deffn + +@deffn procedure fdes->outport fdes +Returns an existing output port which has @var{fdes} as its underlying file +descriptor, if one exists, and increments its revealed count. +Otherwise, returns a new output port with a revealed count of 1. +@end deffn + +@deffn primitive primitive-move->fdes port fd +Moves the underlying file descriptor for @var{port} to the integer +value @var{fdes} without changing the revealed count of @var{port}. +Any other ports already using this descriptor will be automatically +shifted to new descriptors and their revealed counts reset to zero. +The return value is @code{#f} if the file descriptor already had the +required value or @code{#t} if it was moved. +@end deffn + +@deffn procedure move->fdes port fdes +Moves the underlying file descriptor for @var{port} to the integer +value @var{fdes} and sets its revealed count to one. Any other ports +already using this descriptor will be automatically +shifted to new descriptors and their revealed counts reset to zero. +The return value is unspecified. +@end deffn + +@deffn procedure release-port-handle port +Decrements the revealed count for a port. +@end deffn + +@deffn primitive fsync object +Copies any unwritten data for the specified output file descriptor to disk. +If @var{port/fd} is a port, its buffer is flushed before the underlying +file descriptor is fsync'd. +The return value is unspecified. +@end deffn + +@deffn primitive open path flags [mode] +Open the file named by @var{path} for reading and/or writing. +@var{flags} is an integer specifying how the file should be opened. +@var{mode} is an integer specifying the permission bits of the file, if +it needs to be created, before the umask is applied. The default is 666 +(Unix itself has no default). + +@var{flags} can be constructed by combining variables using @code{logior}. +Basic flags are: + +@defvar O_RDONLY +Open the file read-only. +@end defvar +@defvar O_WRONLY +Open the file write-only. +@end defvar +@defvar O_RDWR +Open the file read/write. +@end defvar +@defvar O_APPEND +Append to the file instead of truncating. +@end defvar +@defvar O_CREAT +Create the file if it does not already exist. +@end defvar + +See the Unix documentation of the @code{open} system call +for additional flags. +@end deffn + +@deffn primitive open-fdes path flags [mode] +Similar to @code{open} but return a file descriptor instead of +a port. +@end deffn + +@deffn primitive close fd_or_port +Similar to close-port (@pxref{Closing, close-port}), but also works on +file descriptors. A side effect of closing a file descriptor is that +any ports using that file descriptor are moved to a different file +descriptor and have their revealed counts set to zero. +@end deffn + +@deffn primitive close-fdes fd +A simple wrapper for the @code{close} system call. +Close file descriptor @var{fd}, which must be an integer. +Unlike close (@pxref{Ports and File Descriptors, close}), +the file descriptor will be closed even if a port is using it. +The return value is unspecified. +@end deffn + +@deffn primitive unread-char char [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 primitive unread-string str port +Place the string @var{str} in @var{port} so that its characters will be +read in subsequent read operations. If called multiple times, the +unread characters will be read again in last-in first-out order. If +@var{port} is not supplied, the current-input-port is used. +@end deffn + +@deffn primitive pipe +Return a newly created pipe: a pair of ports which are linked +together on the local machine. The @emph{car} is the input +port and the @emph{cdr} is the output port. Data written (and +flushed) to the output port can be read from the input port. +Pipes are commonly used for communication with a newly forked +child process. The need to flush the output port can be +avoided by making it unbuffered using @code{setvbuf}. + +Writes occur atomically provided the size of the data in bytes +is not greater than the value of @code{PIPE_BUF}. Note that +the output port is likely to block if too much data (typically +equal to @code{PIPE_BUF}) has been written but not yet read +from the input port. +@end deffn + +The next group of procedures perform a @code{dup2} +system call, if @var{newfd} (an +integer) is supplied, otherwise a @code{dup}. The file descriptor to be +duplicated can be supplied as an integer or contained in a port. The +type of value returned varies depending on which procedure is used. + +All procedures also have the side effect when performing @code{dup2} that any +ports using @var{newfd} are moved to a different file descriptor and have +their revealed counts set to zero. + +@deffn primitive dup->fdes fd_or_port [fd] +Return a new integer file descriptor referring to the open file +designated by @var{fd_or_port}, which must be either an open +file port or a file descriptor. +@end deffn + +@deffn procedure dup->inport port/fd [newfd] +Returns a new input port using the new file descriptor. +@end deffn + +@deffn procedure dup->outport port/fd [newfd] +Returns a new output port using the new file descriptor. +@end deffn + +@deffn procedure dup port/fd [newfd] +Returns a new port if @var{port/fd} is a port, with the same mode as the +supplied port, otherwise returns an integer file descriptor. +@end deffn + +@deffn procedure dup->port port/fd mode [newfd] +Returns a new port using the new file descriptor. @var{mode} supplies a +mode string for the port (@pxref{File Ports, open-file}). +@end deffn + +@deffn procedure duplicate-port port modes +Returns a new port which is opened on a duplicate of the file +descriptor underlying @var{port}, with mode string @var{modes} +as for @ref{File Ports, open-file}. The two ports +will share a file position and file status flags. + +Unexpected behaviour can result if both ports are subsequently used +and the original and/or duplicate ports are buffered. +The mode string can include @code{0} to obtain an unbuffered duplicate +port. + +This procedure is equivalent to @code{(dup->port @var{port} @var{modes})}. +@end deffn + +@deffn primitive redirect-port old new +This procedure takes two ports and duplicates the underlying file +descriptor from @var{old-port} into @var{new-port}. The +current file descriptor in @var{new-port} will be closed. +After the redirection the two ports will share a file position +and file status flags. + +The return value is unspecified. + +Unexpected behaviour can result if both ports are subsequently used +and the original and/or duplicate ports are buffered. + +This procedure does not have any side effects on other ports or +revealed counts. +@end deffn + +@deffn primitive dup2 oldfd newfd +A simple wrapper for the @code{dup2} system call. +Copies the file descriptor @var{oldfd} to descriptor +number @var{newfd}, replacing the previous meaning +of @var{newfd}. Both @var{oldfd} and @var{newfd} must +be integers. +Unlike for dup->fdes or primitive-move->fdes, no attempt +is made to move away ports which are using @var{newfd}. +The return value is unspecified. +@end deffn + +@deffn primitive 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 primitive close-all-ports-except . ports +[DEPRECATED] Close all open file ports used by the interpreter +except for those supplied as arguments. This procedure +was intended to be used before an exec call to close file descriptors +which are not needed in the new process. However it has the +undesirable side-effect of flushing buffes, so it's deprecated. +Use port-for-each instead. +@end deffn + +@deffn primitive port-for-each proc +Apply @var{proc} to each port in the Guile port table +in turn. The return value is unspecified. More specifically, +@var{proc} is applied exactly once to every port that exists +in the system at the time @var{port-for-each} is invoked. +Changes to the port table while @var{port-for-each} is running +have no effect as far as @var{port-for-each} is concerned. +@end deffn + +@deffn primitive setvbuf port mode [size] +Set the buffering mode for @var{port}. @var{mode} can be: +@table @code +@item _IONBF +non-buffered +@item _IOLBF +line buffered +@item _IOFBF +block buffered, using a newly allocated buffer of @var{size} bytes. +If @var{size} is omitted, a default size will be used. +@end table +@end deffn + +@deffn primitive fcntl object cmd [value] +Apply @var{command} to the specified file descriptor or the underlying +file descriptor of the specified port. @var{value} is an optional +integer argument. + +Values for @var{command} are: + +@table @code +@item F_DUPFD +Duplicate a file descriptor +@item F_GETFD +Get flags associated with the file descriptor. +@item F_SETFD +Set flags associated with the file descriptor to @var{value}. +@item F_GETFL +Get flags associated with the open file. +@item F_SETFL +Set flags associated with the open file to @var{value} +@item F_GETOWN +Get the process ID of a socket's owner, for @code{SIGIO} signals. +@item F_SETOWN +Set the process that owns a socket to @var{value}, for @code{SIGIO} signals. +@item FD_CLOEXEC +The value used to indicate the "close on exec" flag with @code{F_GETFL} or +@code{F_SETFL}. +@end table +@end deffn + +@deffn primitive flock file operation +Apply or remove an advisory lock on an open file. +@var{operation} specifies the action to be done: +@table @code +@item LOCK_SH +Shared lock. More than one process may hold a shared lock +for a given file at a given time. +@item LOCK_EX +Exclusive lock. Only one process may hold an exclusive lock +for a given file at a given time. +@item LOCK_UN +Unlock the file. +@item LOCK_NB +Don't block when locking. May be specified by bitwise OR'ing +it to one of the other operations. +@end table +The return value is not specified. @var{file} may be an open +file descriptor or an open file descriptior port. +@end deffn + +@deffn primitive select reads writes excepts [secs [usecs]] +This procedure has a variety of uses: waiting for the ability +to provide input, accept output, or the existance of +exceptional conditions on a collection of ports or file +descriptors, or waiting for a timeout to occur. +It also returns if interrupted by a signal. + +@var{reads}, @var{writes} and @var{excepts} can be lists or +vectors, with each member a port or a file descriptor. +The value returned is a list of three corresponding +lists or vectors containing only the members which meet the +specified requirement. The ability of port buffers to +provide input or accept output is taken into account. +Ordering of the input lists or vectors is not preserved. + +The optional arguments @var{secs} and @var{usecs} specify the +timeout. Either @var{secs} can be specified alone, as +either an integer or a real number, or both @var{secs} and +@var{usecs} can be specified as integers, in which case +@var{usecs} is an additional timeout expressed in +microseconds. If @var{secs} is omitted or is @code{#f} then +select will wait for as long as it takes for one of the other +conditions to be satisfied. + +The scsh version of @code{select} differs as follows: +Only vectors are accepted for the first three arguments. +The @var{usecs} argument is not supported. +Multiple values are returned instead of a list. +Duplicates in the input vectors appear only once in output. +An additional @code{select!} interface is provided. +@end deffn + +@node File System +@section File System + +These procedures allow querying and setting file system attributes +(such as owner, +permissions, sizes and types of files); deleting, copying, renaming and +linking files; creating and removing directories and querying their +contents; syncing the file system and creating special files. + +@deffn primitive access? path how +Return @code{#t} if @var{path} corresponds to an existing file +and the current process has the type of access specified by +@var{how}, otherwise @code{#f}. @var{how} should be specified +using the values of the variables listed below. Multiple +values can be combined using a bitwise or, in which case +@code{#t} will only be returned if all accesses are granted. + +Permissions are checked using the real id of the current +process, not the effective id, although it's the effective id +which determines whether the access would actually be granted. + +@defvar R_OK +test for read permission. +@end defvar +@defvar W_OK +test for write permission. +@end defvar +@defvar X_OK +test for execute permission. +@end defvar +@defvar F_OK +test for existence of the file. +@end defvar +@end deffn + +@findex fstat +@deffn primitive stat object +Return an object containing various information about the file +determined by @var{obj}. @var{obj} can be a string containing +a file name or a port or integer file descriptor which is open +on a file (in which case @code{fstat} is used as the underlying +system call). + +The object returned by @code{stat} can be passed as a single +parameter to the following procedures, all of which return +integers: + +@table @code +@item stat:dev +The device containing the file. +@item stat:ino +The file serial number, which distinguishes this file from all +other files on the same device. +@item stat:mode +The mode of the file. This includes file type information and +the file permission bits. See @code{stat:type} and +@code{stat:perms} below. +@item stat:nlink +The number of hard links to the file. +@item stat:uid +The user ID of the file's owner. +@item stat:gid +The group ID of the file. +@item stat:rdev +Device ID; this entry is defined only for character or block +special files. +@item stat:size +The size of a regular file in bytes. +@item stat:atime +The last access time for the file. +@item stat:mtime +The last modification time for the file. +@item stat:ctime +The last modification time for the attributes of the file. +@item stat:blksize +The optimal block size for reading or writing the file, in +bytes. +@item stat:blocks +The amount of disk space that the file occupies measured in +units of 512 byte blocks. +@end table + +In addition, the following procedures return the information +from stat:mode in a more convenient form: + +@table @code +@item stat:type +A symbol representing the type of file. Possible values are +regular, directory, symlink, block-special, char-special, fifo, +socket and unknown +@item stat:perms +An integer representing the access permission bits. +@end table +@end deffn + +@deffn primitive lstat str +Similar to @code{stat}, but does not follow symbolic links, i.e., +it will return information about a symbolic link itself, not the +file it points to. @var{path} must be a string. +@end deffn + +@deffn primitive readlink path +Return the value of the symbolic link named by @var{path} (a +string), i.e., the file that the link points to. +@end deffn + +@findex fchown +@findex lchown +@deffn primitive chown object owner group +Change the ownership and group of the file referred to by @var{object} to +the integer values @var{owner} and @var{group}. @var{object} can be +a string containing a file name or, if the platform +supports fchown, a port or integer file descriptor +which is open on the file. The return value +is unspecified. + +If @var{object} is a symbolic link, either the +ownership of the link or the ownership of the referenced file will be +changed depending on the operating system (lchown is +unsupported at present). If @var{owner} or @var{group} is specified +as @code{-1}, then that ID is not changed. +@end deffn + +@findex fchmod +@deffn primitive chmod object mode +Changes the permissions of the file referred to by @var{obj}. +@var{obj} can be a string containing a file name or a port or integer file +descriptor which is open on a file (in which case @code{fchmod} is used +as the underlying system call). +@var{mode} specifies +the new permissions as a decimal number, e.g., @code{(chmod "foo" #o755)}. +The return value is unspecified. +@end deffn + +@deffn primitive utime pathname [actime [modtime]] +@code{utime} sets the access and modification times for the +file named by @var{path}. If @var{actime} or @var{modtime} is +not supplied, then the current time is used. @var{actime} and +@var{modtime} must be integer time values as returned by the +@code{current-time} procedure. +@lisp +(utime "foo" (- (current-time) 3600)) +@end lisp +will set the access time to one hour in the past and the +modification time to the current time. +@end deffn + +@findex unlink +@deffn primitive delete-file str +Deletes (or "unlinks") the file specified by @var{path}. +@end deffn + +@deffn primitive copy-file oldfile newfile +Copy the file specified by @var{path-from} to @var{path-to}. +The return value is unspecified. +@end deffn + +@findex rename +@deffn primitive rename-file oldname newname +Renames the file specified by @var{oldname} to @var{newname}. +The return value is unspecified. +@end deffn + +@deffn primitive link oldpath newpath +Creates a new name @var{newpath} in the file system for the +file named by @var{oldpath}. If @var{oldpath} is a symbolic +link, the link may or may not be followed depending on the +system. +@end deffn + +@deffn primitive symlink oldpath newpath +Create a symbolic link named @var{path-to} with the value (i.e., pointing to) +@var{path-from}. The return value is unspecified. +@end deffn + +@deffn primitive mkdir path [mode] +Create a new directory named by @var{path}. If @var{mode} is omitted +then the permissions of the directory file are set using the current +umask. Otherwise they are set to the decimal value specified with +@var{mode}. The return value is unspecified. +@end deffn + +@deffn primitive rmdir path +Remove the existing directory named by @var{path}. The directory must +be empty for this to succeed. The return value is unspecified. +@end deffn + +@deffn primitive opendir dirname +Open the directory specified by @var{path} and return a directory +stream. +@end deffn + +@deffn primitive directory-stream? obj +Return a boolean indicating whether @var{object} is a directory +stream as returned by @code{opendir}. +@end deffn + +@deffn primitive readdir port +Return (as a string) the next directory entry from the directory stream +@var{stream}. If there is no remaining entry to be read then the +end of file object is returned. +@end deffn + +@deffn primitive rewinddir port +Reset the directory port @var{stream} so that the next call to +@code{readdir} will return the first directory entry. +@end deffn + +@deffn primitive closedir port +Close the directory stream @var{stream}. +The return value is unspecified. +@end deffn + +@deffn primitive sync +Flush the operating system disk buffers. +The return value is unspecified. +@end deffn + +@deffn primitive mknod path type perms dev +Creates a new special file, such as a file corresponding to a device. +@var{path} specifies the name of the file. @var{type} should +be one of the following symbols: +regular, directory, symlink, block-special, char-special, +fifo, or socket. @var{perms} (an integer) specifies the file permissions. +@var{dev} (an integer) specifies which device the special file refers +to. Its exact interpretation depends on the kind of special file +being created. + +E.g., +@lisp +(mknod "/dev/fd0" 'block-special #o660 (+ (* 2 256) 2)) +@end lisp + +The return value is unspecified. +@end deffn + +@deffn primitive tmpnam +Return a name in the file system that does not match any +existing file. However there is no guarantee that another +process will not create the file after @code{tmpnam} is called. +Care should be taken if opening the file, e.g., use the +@code{O_EXCL} open flag or use @code{mkstemp!} instead. +@end deffn + +@deffn primitive mkstemp! tmpl +Create a new unique file in the file system and returns a new +buffered port open for reading and writing to the file. +@var{tmpl} is a string specifying where the file should be +created: it must end with @code{XXXXXX} and will be changed in +place to return the name of the temporary file. +@end deffn + +@deffn primitive dirname filename +Return the directory name component of the file name +@var{filename}. If @var{filename} does not contain a directory +component, @code{.} is returned. +@end deffn + +@deffn primitive basename filename [suffix] +Return the base name of the file name @var{filename}. The +base name is the file name without any directory components. +If @var{suffix} is privided, and is equal to the end of +@var{basename}, it is removed also. +@end deffn + + +@node User Information +@section User Information + +The facilities in this section provide an interface to the user and +group database. +They should be used with care since they are not reentrant. + +The following functions accept an object representing user information +and return a selected component: + +@table @code +@item passwd:name +The name of the userid. +@item passwd:passwd +The encrypted passwd. +@item passwd:uid +The user id number. +@item passwd:gid +The group id number. +@item passwd:gecos +The full name. +@item passwd:dir +The home directory. +@item passwd:shell +The login shell. +@end table + +@deffn procedure getpwuid uid +Look up an integer userid in the user database. +@end deffn + +@deffn procedure getpwnam name +Look up a user name string in the user database. +@end deffn + +@deffn procedure setpwent +Initializes a stream used by @code{getpwent} to read from the user database. +The next use of @code{getpwent} will return the first entry. The +return value is unspecified. +@end deffn + +@deffn procedure getpwent +Return the next entry in the user database, using the stream set by +@code{setpwent}. +@end deffn + +@deffn procedure endpwent +Closes the stream used by @code{getpwent}. The return value is unspecified. +@end deffn + +@deffn primitive setpw [arg] +If called with a true argument, initialize or reset the password data +stream. Otherwise, close the stream. The @code{setpwent} and +@code{endpwent} procedures are implemented on top of this. +@end deffn + +@deffn primitive getpw [user] +Look up an entry in the user database. @var{obj} can be an integer, +a string, or omitted, giving the behaviour of getpwuid, getpwnam +or getpwent respectively. +@end deffn + +The following functions accept an object representing group information +and return a selected component: + +@table @code +@item group:name +The group name. +@item group:passwd +The encrypted group password. +@item group:gid +The group id number. +@item group:mem +A list of userids which have this group as a supplimentary group. +@end table + +@deffn procedure getgrgid gid +Look up an integer groupid in the group database. +@end deffn + +@deffn procedure getgrnam name +Look up a group name in the group database. +@end deffn + +@deffn procedure setgrent +Initializes a stream used by @code{getgrent} to read from the group database. +The next use of @code{getgrent} will return the first entry. +The return value is unspecified. +@end deffn + +@deffn procedure getgrent +Return the next entry in the group database, using the stream set by +@code{setgrent}. +@end deffn + +@deffn procedure endgrent +Closes the stream used by @code{getgrent}. +The return value is unspecified. +@end deffn + +@deffn primitive setgr [arg] +If called with a true argument, initialize or reset the group data +stream. Otherwise, close the stream. The @code{setgrent} and +@code{endgrent} procedures are implemented on top of this. +@end deffn + +@deffn primitive getgr [name] +Look up an entry in the group database. @var{obj} can be an integer, +a string, or omitted, giving the behaviour of getgrgid, getgrnam +or getgrent respectively. +@end deffn + +In addition to the accessor procedures for the user database, the +following shortcut procedures are also available. + +@deffn primitive cuserid +Return a string containing a user name associated with the +effective user id of the process. Return @code{#f} if this +information cannot be obtained. +@end deffn + +@deffn primitive getlogin +Return a string containing the name of the user logged in on +the controlling terminal of the process, or @code{#f} if this +information cannot be obtained. +@end deffn + + +@node Time +@section Time + +@deffn primitive current-time +Return the number of seconds since 1970-01-01 00:00:00 UTC, +excluding leap seconds. +@end deffn + +@deffn primitive gettimeofday +Return a pair containing the number of seconds and microseconds +since 1970-01-01 00:00:00 UTC, excluding leap seconds. Note: +whether true microsecond resolution is available depends on the +operating system. +@end deffn + +The following procedures either accept an object representing a broken down +time and return a selected component, or accept an object representing +a broken down time and a value and set the component to the value. +The numbers in parentheses give the usual range. + +@table @code +@item tm:sec, set-tm:sec +Seconds (0-59). +@item tm:min, set-tm:min +Minutes (0-59). +@item tm:hour, set-tm:hour +Hours (0-23). +@item tm:mday, set-tm:mday +Day of the month (1-31). +@item tm:mon, set-tm:mon +Month (0-11). +@item tm:year, set-tm:year +Year (70-), the year minus 1900. +@item tm:wday, set-tm:wday +Day of the week (0-6) with Sunday represented as 0. +@item tm:yday, set-tm:yday +Day of the year (0-364, 365 in leap years). +@item tm:isdst, set-tm:isdst +Daylight saving indicator (0 for "no", greater than 0 for "yes", less than +0 for "unknown"). +@item tm:gmtoff, set-tm:gmtoff +Time zone offset in seconds west of UTC (-46800 to 43200). +@item tm:zone, set-tm:zone +Time zone label (a string), not necessarily unique. +@end table + +@deffn primitive localtime time [zone] +Return an object representing the broken down components of +@var{time}, an integer like the one returned by +@code{current-time}. The time zone for the calculation is +optionally specified by @var{zone} (a string), otherwise the +@code{TZ} environment variable or the system default is used. +@end deffn + +@deffn primitive gmtime time +Return an object representing the broken down components of +@var{time}, an integer like the one returned by +@code{current-time}. The values are calculated for UTC. +@end deffn + +@deffn primitive mktime sbd_time [zone] +@var{bd-time} is an object representing broken down time and @code{zone} +is an optional time zone specifier (otherwise the TZ environment variable +or the system default is used). + +Returns a pair: the car is a corresponding +integer time value like that returned +by @code{current-time}; the cdr is a broken down time object, similar to +as @var{bd-time} but with normalized values. +@end deffn + +@deffn primitive tzset +Initialize the timezone from the TZ environment variable +or the system default. It's not usually necessary to call this procedure +since it's done automatically by other procedures that depend on the +timezone. +@end deffn + +@deffn primitive strftime format stime +Formats a time specification @var{time} using @var{template}. @var{time} +is an object with time components in the form returned by @code{localtime} +or @code{gmtime}. @var{template} is a string which can include formatting +specifications introduced by a @code{%} character. The formatting of +month and day names is dependent on the current locale. The value returned +is the formatted string. +@xref{Formatting Date and Time, , , libc, The GNU C Library Reference Manual}.) +@end deffn + +@deffn primitive strptime format string +Performs the reverse action to @code{strftime}, parsing +@var{string} according to the specification supplied in +@var{template}. The interpretation of month and day names is +dependent on the current locale. The value returned is a pair. +The car has an object with time components +in the form returned by @code{localtime} or @code{gmtime}, +but the time zone components +are not usefully set. +The cdr reports the number of characters from @var{string} +which were used for the conversion. +@end deffn + +@defvar internal-time-units-per-second +The value of this variable is the number of time units per second +reported by the following procedures. +@end defvar + +@deffn primitive times +Return an object with information about real and processor +time. The following procedures accept such an object as an +argument and return a selected component: + +@table @code +@item tms:clock +The current real time, expressed as time units relative to an +arbitrary base. +@item tms:utime +The CPU time units used by the calling process. +@item tms:stime +The CPU time units used by the system on behalf of the calling +process. +@item tms:cutime +The CPU time units used by terminated child processes of the +calling process, whose status has been collected (e.g., using +@code{waitpid}). +@item tms:cstime +Similarly, the CPU times units used by the system on behalf of +terminated child processes. +@end table +@end deffn + +@deffn primitive get-internal-real-time +Return the number of time units since the interpreter was +started. +@end deffn + +@deffn primitive get-internal-run-time +Return the number of time units of processor time used by the +interpreter. Both @emph{system} and @emph{user} time are +included but subprocesses are not. +@end deffn + +@node Runtime Environment +@section Runtime Environment + +@deffn primitive program-arguments +@deffnx procedure command-line +Return the list of command line arguments passed to Guile, as a list of +strings. The list includes the invoked program name, which is usually +@code{"guile"}, but excludes switches and parameters for command line +options like @code{-e} and @code{-l}. +@end deffn + +@deffn primitive getenv nam +Looks up the string @var{name} in the current environment. The return +value is @code{#f} unless a string of the form @code{NAME=VALUE} is +found, in which case the string @code{VALUE} is returned. +@end deffn + +@c begin (scm-doc-string "boot-9.scm" "setenv") +@deffn procedure setenv name value +Modifies the environment of the current process, which is +also the default environment inherited by child processes. + +If @var{value} is @code{#f}, then @var{name} is removed from the +environment. Otherwise, the string @var{name}=@var{value} is added +to the environment, replacing any existing string with name matching +@var{name}. + +The return value is unspecified. +@end deffn + +@deffn primitive environ [env] +If @var{env} is omitted, return the current environment (in the +Unix sense) as a list of strings. Otherwise set the current +environment, which is also the default environment for child +processes, to the supplied list of strings. Each member of +@var{env} should be of the form @code{NAME=VALUE} and values of +@code{NAME} should not be duplicated. If @var{env} is supplied +then the return value is unspecified. +@end deffn + +@deffn primitive putenv str +Modifies the environment of the current process, which is +also the default environment inherited by child processes. + +If @var{string} is of the form @code{NAME=VALUE} then it will be written +directly into the environment, replacing any existing environment string +with +name matching @code{NAME}. If @var{string} does not contain an equal +sign, then any existing string with name matching @var{string} will +be removed. + +The return value is unspecified. +@end deffn + + +@node Processes +@section Processes + +@findex cd +@deffn primitive chdir str +Change the current working directory to @var{path}. +The return value is unspecified. +@end deffn + +@findex pwd +@deffn primitive getcwd +Return the name of the current working directory. +@end deffn + +@deffn primitive umask [mode] +If @var{mode} is omitted, retuns a decimal number representing the current +file creation mask. Otherwise the file creation mask is set to +@var{mode} and the previous value is returned. + +E.g., @code{(umask #o022)} sets the mask to octal 22, decimal 18. +@end deffn + +@deffn primitive chroot path +Change the root directory to that specified in @var{path}. +This directory will be used for path names beginning with +@file{/}. The root directory is inherited by all children +of the current process. Only the superuser may change the +root directory. +@end deffn + +@deffn primitive getpid +Return an integer representing the current process ID. +@end deffn + +@deffn primitive getgroups +Return a vector of integers representing the current +supplimentary group IDs. +@end deffn + +@deffn primitive getppid +Return an integer representing the process ID of the parent +process. +@end deffn + +@deffn primitive getuid +Return an integer representing the current real user ID. +@end deffn + +@deffn primitive getgid +Return an integer representing the current real group ID. +@end deffn + +@deffn primitive geteuid +Return an integer representing the current effective user ID. +If the system does not support effective IDs, then the real ID +is returned. @code{(feature? 'EIDs)} reports whether the +system supports effective IDs. +@end deffn + +@deffn primitive getegid +Return an integer representing the current effective group ID. +If the system does not support effective IDs, then the real ID +is returned. @code{(feature? 'EIDs)} reports whether the +system supports effective IDs. +@end deffn + +@deffn primitive setuid id +Sets both the real and effective user IDs to the integer @var{id}, provided +the process has appropriate privileges. +The return value is unspecified. +@end deffn + +@deffn primitive setgid id +Sets both the real and effective group IDs to the integer @var{id}, provided +the process has appropriate privileges. +The return value is unspecified. +@end deffn + +@deffn primitive seteuid id +Sets the effective user ID to the integer @var{id}, provided the process +has appropriate privileges. If effective IDs are not supported, the +real ID is set instead -- @code{(feature? 'EIDs)} reports whether the +system supports effective IDs. +The return value is unspecified. +@end deffn + +@deffn primitive setegid id +Sets the effective group ID to the integer @var{id}, provided the process +has appropriate privileges. If effective IDs are not supported, the +real ID is set instead -- @code{(feature? 'EIDs)} reports whether the +system supports effective IDs. +The return value is unspecified. +@end deffn + +@deffn primitive getpgrp +Return an integer representing the current process group ID. +This is the POSIX definition, not BSD. +@end deffn + +@deffn primitive setpgid pid pgid +Move the process @var{pid} into the process group @var{pgid}. @var{pid} or +@var{pgid} must be integers: they can be zero to indicate the ID of the +current process. +Fails on systems that do not support job control. +The return value is unspecified. +@end deffn + +@deffn primitive setsid +Creates a new session. The current process becomes the session leader +and is put in a new process group. The process will be detached +from its controlling terminal if it has one. +The return value is an integer representing the new process group ID. +@end deffn + +@deffn primitive waitpid pid [options] +This procedure collects status information from a child process which +has terminated or (optionally) stopped. Normally it will +suspend the calling process until this can be done. If more than one +child process is eligible then one will be chosen by the operating system. + +The value of @var{pid} determines the behaviour: + +@table @r +@item @var{pid} greater than 0 +Request status information from the specified child process. +@item @var{pid} equal to -1 or WAIT_ANY +Request status information for any child process. +@item @var{pid} equal to 0 or WAIT_MYPGRP +Request status information for any child process in the current process +group. +@item @var{pid} less than -1 +Request status information for any child process whose process group ID +is -@var{PID}. +@end table + +The @var{options} argument, if supplied, should be the bitwise OR of the +values of zero or more of the following variables: + +@defvar WNOHANG +Return immediately even if there are no child processes to be collected. +@end defvar + +@defvar WUNTRACED +Report status information for stopped processes as well as terminated +processes. +@end defvar + +The return value is a pair containing: + +@enumerate +@item +The process ID of the child process, or 0 if @code{WNOHANG} was +specified and no process was collected. +@item +The integer status value. +@end enumerate +@end deffn + +The following three +functions can be used to decode the process status code returned +by @code{waitpid}. + +@deffn primitive status:exit-val status +Return the exit status value, as would be set if a process +ended normally through a call to @code{exit} or @code{_exit}, +if any, otherwise @code{#f}. +@end deffn + +@deffn primitive status:term-sig status +Return the signal number which terminated the process, if any, +otherwise @code{#f}. +@end deffn + +@deffn primitive status:stop-sig status +Return the signal number which stopped the process, if any, +otherwise @code{#f}. +@end deffn + +@deffn primitive system [cmd] +Execute @var{cmd} using the operating system's "command +processor". Under Unix this is usually the default shell +@code{sh}. The value returned is @var{cmd}'s exit status as +returned by @code{waitpid}, which can be interpreted using the +functions above. + +If @code{system} is called without arguments, return a boolean +indicating whether the command processor is available. +@end deffn + +@deffn primitive primitive-exit [status] +Terminate the current process without unwinding the Scheme stack. +This is would typically be useful after a fork. The exit status +is @var{status} if supplied, otherwise zero. +@end deffn + +@deffn primitive execl filename . args +Executes the file named by @var{path} as a new process image. +The remaining arguments are supplied to the process; from a C program +they are accessable as the @code{argv} argument to @code{main}. +Conventionally the first @var{arg} is the same as @var{path}. +All arguments must be strings. + +If @var{arg} is missing, @var{path} is executed with a null +argument list, which may have system-dependent side-effects. + +This procedure is currently implemented using the @code{execv} system +call, but we call it @code{execl} because of its Scheme calling interface. +@end deffn + +@deffn primitive execlp filename . args +Similar to @code{execl}, however if +@var{filename} does not contain a slash +then the file to execute will be located by searching the +directories listed in the @code{PATH} environment variable. + +This procedure is currently implemented using the @code{execvp} system +call, but we call it @code{execlp} because of its Scheme calling interface. +@end deffn + +@deffn primitive execle filename env . args +Similar to @code{execl}, but the environment of the new process is +specified by @var{env}, which must be a list of strings as returned by the +@code{environ} procedure. + +This procedure is currently implemented using the @code{execve} system +call, but we call it @code{execle} because of its Scheme calling interface. +@end deffn + +@deffn primitive primitive-fork +Creates a new "child" process by duplicating the current "parent" process. +In the child the return value is 0. In the parent the return value is +the integer process ID of the child. + +This procedure has been renamed from @code{fork} to avoid a naming conflict +with the scsh fork. +@end deffn + +@deffn primitive nice incr +Increment the priority of the current process by @var{incr}. A higher +priority value means that the process runs less often. +The return value is unspecified. +@end deffn + +@deffn primitive setpriority which who prio +Set the scheduling priority of the process, process group +or user, as indicated by @var{which} and @var{who}. @var{which} +is one of the variables @code{PRIO_PROCESS}, @code{PRIO_PGRP} +or @code{PRIO_USER}, and @var{who} is interpreted relative to +@var{which} (a process identifier for @code{PRIO_PROCESS}, +process group identifier for @code{PRIO_PGRP}, and a user +identifier for @code{PRIO_USER}. A zero value of @var{who} +denotes the current process, process group, or user. +@var{prio} is a value in the range -20 and 20, the default +priority is 0; lower priorities cause more favorable +scheduling. Sets the priority of all of the specified +processes. Only the super-user may lower priorities. +The return value is not specified. +@end deffn + +@deffn primitive getpriority which who +Return the scheduling priority of the process, process group +or user, as indicated by @var{which} and @var{who}. @var{which} +is one of the variables @code{PRIO_PROCESS}, @code{PRIO_PGRP} +or @code{PRIO_USER}, and @var{who} is interpreted relative to +@var{which} (a process identifier for @code{PRIO_PROCESS}, +process group identifier for @code{PRIO_PGRP}, and a user +identifier for @code{PRIO_USER}. A zero value of @var{who} +denotes the current process, process group, or user. Return +the highest priority (lowest numerical value) of any of the +specified processes. +@end deffn + + +@node Signals +@section Signals + +Procedures to raise, handle and wait for signals. + +@deffn primitive kill pid sig +Sends a signal to the specified process or group of processes. + +@var{pid} specifies the processes to which the signal is sent: + +@table @r +@item @var{pid} greater than 0 +The process whose identifier is @var{pid}. +@item @var{pid} equal to 0 +All processes in the current process group. +@item @var{pid} less than -1 +The process group whose identifier is -@var{pid} +@item @var{pid} equal to -1 +If the process is privileged, all processes except for some special +system processes. Otherwise, all processes with the current effective +user ID. +@end table + +@var{sig} should be specified using a variable corresponding to +the Unix symbolic name, e.g., + +@defvar SIGHUP +Hang-up signal. +@end defvar + +@defvar SIGINT +Interrupt signal. +@end defvar +@end deffn + +@deffn primitive raise sig +Sends a specified signal @var{sig} to the current process, where +@var{sig} is as described for the kill procedure. +@end deffn + +@deffn primitive sigaction signum [handler [flags]] +Install or report the signal handler for a specified signal. + +@var{signum} is the signal number, which can be specified using the value +of variables such as @code{SIGINT}. + +If @var{action} is omitted, @code{sigaction} returns a pair: the +CAR is the current +signal hander, which will be either an integer with the value @code{SIG_DFL} +(default action) or @code{SIG_IGN} (ignore), or the Scheme procedure which +handles the signal, or @code{#f} if a non-Scheme procedure handles the +signal. The CDR contains the current @code{sigaction} flags for the handler. + +If @var{action} is provided, it is installed as the new handler for +@var{signum}. @var{action} can be a Scheme procedure taking one +argument, or the value of @code{SIG_DFL} (default action) or +@code{SIG_IGN} (ignore), or @code{#f} to restore whatever signal handler +was installed before @code{sigaction} was first used. Flags can +optionally be specified for the new handler (@code{SA_RESTART} will +always be added if it's available and the system is using restartable +system calls.) The return value is a pair with information about the +old handler as described above. + +This interface does not provide access to the "signal blocking" +facility. Maybe this is not needed, since the thread support may +provide solutions to the problem of consistent access to data +structures. +@end deffn + +@deffn primitive restore-signals +Return all signal handlers to the values they had before any call to +@code{sigaction} was made. The return value is unspecified. +@end deffn + +@deffn primitive alarm i +Set a timer to raise a @code{SIGALRM} signal after the specified +number of seconds (an integer). It's advisable to install a signal +handler for +@code{SIGALRM} beforehand, since the default action is to terminate +the process. + +The return value indicates the time remaining for the previous alarm, +if any. The new value replaces the previous alarm. If there was +no previous alarm, the return value is zero. +@end deffn + +@deffn primitive pause +Pause the current process (thread?) until a signal arrives whose +action is to either terminate the current process or invoke a +handler procedure. The return value is unspecified. +@end deffn + +@deffn primitive sleep i +Wait for the given number of seconds (an integer) or until a signal +arrives. The return value is zero if the time elapses or the number +of seconds remaining otherwise. +@end deffn + +@deffn primitive usleep i +Sleep for I microseconds. @code{usleep} is not available on +all platforms. +@end deffn + +@deffn primitive setitimer which_timer interval_seconds interval_microseconds value_seconds value_microseconds + +Set the timer specified by @var{which_timer} according to the given +@var{interval_seconds}, @var{interval_microseconds}, +@var{value_seconds}, and @var{value_microseconds} values, and return +information about the timer's previous setting. The timers available +are: @code{ITIMER_REAL}, @code{ITIMER_VIRTUAL}, and @code{ITIMER_PROF}, +and the return value will be a list of two cons pairs representing the +current state of the given timer. The first pair is the seconds and +microseconds of the timer @code{it_interval}, and the second pair is the +seconds and microseconds of the timer @code{it_value}. +@end deffn + +@deffn primitive getitimer which_timer +Return information about the timer specified by @var{which_timer}. The +timers available are: @code{ITIMER_REAL}, @code{ITIMER_VIRTUAL}, and +@code{ITIMER_PROF}, and the return value will be a list of two cons +pairs representing the current state of the given timer. The first pair +is the seconds and microseconds of the timer @code{it_interval}, and the +second pair is the seconds and microseconds of the timer +@code{it_value}. +@end deffn + + +@node Terminals and Ptys +@section Terminals and Ptys + +@deffn primitive isatty? port +Return @code{#t} if @var{port} is using a serial non--file +device, otherwise @code{#f}. +@end deffn + +@deffn primitive ttyname port +Return a string with the name of the serial terminal device +underlying @var{port}. +@end deffn + +@deffn primitive ctermid +Return a string containing the file name of the controlling +terminal for the current process. +@end deffn + +@deffn primitive tcgetpgrp port +Return the process group ID of the foreground process group +associated with the terminal open on the file descriptor +underlying @var{port}. + +If there is no foreground process group, the return value is a +number greater than 1 that does not match the process group ID +of any existing process group. This can happen if all of the +processes in the job that was formerly the foreground job have +terminated, and no other job has yet been moved into the +foreground. +@end deffn + +@deffn primitive tcsetpgrp port pgid +Set the foreground process group ID for the terminal used by the file +descriptor underlying @var{port} to the integer @var{pgid}. +The calling process +must be a member of the same session as @var{pgid} and must have the same +controlling terminal. The return value is unspecified. +@end deffn + +@node Pipes +@section Pipes + +The following procedures provide an interface to the @code{popen} and +@code{pclose} system routines. The code is in a separate "popen" +module: + +@smalllisp +(use-modules (ice-9 popen)) +@end smalllisp + +@findex popen +@deffn procedure open-pipe command modes +Executes the shell command @var{command} (a string) in a subprocess. +A pipe to the process is created and returned. @var{modes} specifies +whether an input or output pipe to the process is created: it should +be the value of @code{OPEN_READ} or @code{OPEN_WRITE}. +@end deffn + +@deffn procedure open-input-pipe command +Equivalent to @code{open-pipe} with mode @code{OPEN_READ}. +@end deffn + +@deffn procedure open-output-pipe command +Equivalent to @code{open-pipe} with mode @code{OPEN_WRITE}. +@end deffn + +@findex pclose +@deffn procedure close-pipe port +Closes the pipe created by @code{open-pipe}, then waits for the process +to terminate and returns its status value, @xref{Processes, waitpid}, for +information on how to interpret this value. + +@code{close-port} (@pxref{Closing, close-port}) can also be used to +close a pipe, but doesn't return the status. +@end deffn + +@node Networking +@section Networking + +@menu +* Network Address Conversion:: +* Network Databases:: +* Network Sockets and Communication:: +@end menu + +@node Network Address Conversion +@subsection Network Address Conversion + +This section describes procedures which convert internet addresses +between numeric and string formats. + +@subsubsection IPv4 Address Conversion + +@deffn primitive inet-aton address +Convert an IPv4 Internet address from printable string +(dotted decimal notation) to an integer. E.g., + +@lisp +(inet-aton "127.0.0.1") @result{} 2130706433 +@end lisp +@end deffn + +@deffn primitive inet-ntoa inetid +Convert an IPv4 Internet address to a printable +(dotted decimal notation) string. E.g., + +@lisp +(inet-ntoa 2130706433) @result{} "127.0.0.1" +@end lisp +@end deffn + +@deffn primitive inet-netof address +Return the network number part of the given IPv4 +Internet address. E.g., + +@lisp +(inet-netof 2130706433) @result{} 127 +@end lisp +@end deffn + +@deffn primitive inet-lnaof address +Return the local-address-with-network part of the given +IPv4 Internet address, using the obsolete class A/B/C system. +E.g., + +@lisp +(inet-lnaof 2130706433) @result{} 1 +@end lisp +@end deffn + +@deffn primitive inet-makeaddr net lna +Make an IPv4 Internet address by combining the network number +@var{net} with the local-address-within-network number +@var{lna}. E.g., + +@lisp +(inet-makeaddr 127 1) @result{} 2130706433 +@end lisp +@end deffn + +@subsubsection IPv6 Address Conversion + +@deffn primitive inet-ntop family address +Convert a network address into a printable string. +Note that unlike the C version of this function, +the input is an integer with normal host byte ordering. +@var{family} can be @code{AF_INET} or @code{AF_INET6}. E.g., + +@lisp +(inet-ntop AF_INET 2130706433) @result{} "127.0.0.1" +(inet-ntop AF_INET6 (- (expt 2 128) 1)) @result{} +ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +@end lisp +@end deffn + +@deffn primitive inet-pton family address +Convert a string containing a printable network address to +an integer address. Note that unlike the C version of this +function, +the result is an integer with normal host byte ordering. +@var{family} can be @code{AF_INET} or @code{AF_INET6}. E.g., + +@lisp +(inet-pton AF_INET "127.0.0.1") @result{} 2130706433 +(inet-pton AF_INET6 "::1") @result{} 1 +@end lisp +@end deffn + + +@node Network Databases +@subsection Network Databases + +This section describes procedures which query various network databases. +Care should be taken when using the database routines since they are not +reentrant. + +@subsubsection The Host Database + +A @dfn{host object} is a structure that represents what is known about a +network host, and is the usual way of representing a system's network +identity inside software. + +The following functions accept a host object and return a selected +component: + +@deffn procedure hostent:name host +The "official" hostname for @var{host}. +@end deffn +@deffn procedure hostent:aliases host +A list of aliases for @var{host}. +@end deffn +@deffn procedure hostent:addrtype host +The host address type. For hosts with Internet addresses, this will +return @code{AF_INET}. +@end deffn +@deffn procedure hostent:length host +The length of each address for @var{host}, in bytes. +@end deffn +@deffn procedure hostent:addr-list host +The list of network addresses associated with @var{host}. +@end deffn + +The following procedures are used to search the host database: + +@deffn primitive gethost [host] +@deffnx procedure gethostbyname hostname +@deffnx procedure gethostbyaddr address +Look up a host by name or address, returning a host object. The +@code{gethost} procedure will accept either a string name or an integer +address; if given no arguments, it behaves like @code{gethostent} (see +below). If a name or address is supplied but the address can not be +found, an error will be thrown to one of the keys: +@code{host-not-found}, @code{try-again}, @code{no-recovery} or +@code{no-data}, corresponding to the equivalent @code{h_error} values. +Unusual conditions may result in errors thrown to the +@code{system-error} or @code{misc_error} keys. +@end deffn + +The following procedures may be used to step through the host +database from beginning to end. + +@deffn procedure sethostent [stayopen] +Initialize an internal stream from which host objects may be read. This +procedure must be called before any calls to @code{gethostent}, and may +also be called afterward to reset the host entry stream. If +@var{stayopen} is supplied and is not @code{#f}, the database is not +closed by subsequent @code{gethostbyname} or @code{gethostbyaddr} calls, +possibly giving an efficiency gain. +@end deffn + +@deffn procedure gethostent +Return the next host object from the host database, or @code{#f} if +there are no more hosts to be found (or an error has been encountered). +This procedure may not be used before @code{sethostent} has been called. +@end deffn + +@deffn procedure endhostent +Close the stream used by @code{gethostent}. The return value is unspecified. +@end deffn + +@deffn primitive sethost [stayopen] +If @var{stayopen} is omitted, this is equivalent to @code{endhostent}. +Otherwise it is equivalent to @code{sethostent stayopen}. +@end deffn +@subsubsection The Network Database + +The following functions accept an object representing a network +and return a selected component: + +@deffn procedure netent:name net +The "official" network name. +@end deffn +@deffn procedure netent:aliases net +A list of aliases for the network. +@end deffn +@deffn procedure netent:addrtype net +The type of the network number. Currently, this returns only +@code{AF_INET}. +@end deffn +@deffn procedure netent:net net +The network number. +@end deffn + +The following procedures are used to search the network database: + +@deffn primitive getnet [net] +@deffnx procedure getnetbyname net-name +@deffnx procedure getnetbyaddr net-number +Look up a network by name or net number in the network database. The +@var{net-name} argument must be a string, and the @var{net-number} +argument must be an integer. @code{getnet} will accept either type of +argument, behaving like @code{getnetent} (see below) if no arguments are +given. +@end deffn + +The following procedures may be used to step through the network +database from beginning to end. + +@deffn procedure setnetent [stayopen] +Initialize an internal stream from which network objects may be read. This +procedure must be called before any calls to @code{getnetent}, and may +also be called afterward to reset the net entry stream. If +@var{stayopen} is supplied and is not @code{#f}, the database is not +closed by subsequent @code{getnetbyname} or @code{getnetbyaddr} calls, +possibly giving an efficiency gain. +@end deffn + +@deffn procedure getnetent +Return the next entry from the network database. +@end deffn + +@deffn procedure endnetent +Close the stream used by @code{getnetent}. The return value is unspecified. +@end deffn + +@deffn primitive setnet [stayopen] +If @var{stayopen} is omitted, this is equivalent to @code{endnetent}. +Otherwise it is equivalent to @code{setnetent stayopen}. +@end deffn + +@subsubsection The Protocol Database + +The following functions accept an object representing a protocol +and return a selected component: + +@deffn procedure protoent:name protocol +The "official" protocol name. +@end deffn +@deffn procedure protoent:aliases protocol +A list of aliases for the protocol. +@end deffn +@deffn procedure protoent:proto protocol +The protocol number. +@end deffn + +The following procedures are used to search the protocol database: + +@deffn primitive getproto [protocol] +@deffnx procedure getprotobyname name +@deffnx procedure getprotobynumber number +Look up a network protocol by name or by number. @code{getprotobyname} +takes a string argument, and @code{getprotobynumber} takes an integer +argument. @code{getproto} will accept either type, behaving like +@code{getprotoent} (see below) if no arguments are supplied. +@end deffn + +The following procedures may be used to step through the protocol +database from beginning to end. + +@deffn procedure setprotoent [stayopen] +Initialize an internal stream from which protocol objects may be read. This +procedure must be called before any calls to @code{getprotoent}, and may +also be called afterward to reset the protocol entry stream. If +@var{stayopen} is supplied and is not @code{#f}, the database is not +closed by subsequent @code{getprotobyname} or @code{getprotobynumber} calls, +possibly giving an efficiency gain. +@end deffn + +@deffn procedure getprotoent +Return the next entry from the protocol database. +@end deffn + +@deffn procedure endprotoent +Close the stream used by @code{getprotoent}. The return value is unspecified. +@end deffn + +@deffn primitive setproto [stayopen] +If @var{stayopen} is omitted, this is equivalent to @code{endprotoent}. +Otherwise it is equivalent to @code{setprotoent stayopen}. +@end deffn + +@subsubsection The Service Database + +The following functions accept an object representing a service +and return a selected component: + +@deffn procedure servent:name serv +The "official" name of the network service. +@end deffn +@deffn procedure servent:aliases serv +A list of aliases for the network service. +@end deffn +@deffn procedure servent:port serv +The Internet port used by the service. +@end deffn +@deffn procedure servent:proto serv +The protocol used by the service. A service may be listed many times +in the database under different protocol names. +@end deffn + +The following procedures are used to search the service database: + +@deffn primitive getserv [name [protocol]] +@deffnx procedure getservbyname name protocol +@deffnx procedure getservbyport port protocol +Look up a network service by name or by service number, and return a +network service object. The @var{protocol} argument specifies the name +of the desired protocol; if the protocol found in the network service +database does not match this name, a system error is signalled. + +The @code{getserv} procedure will take either a service name or number +as its first argument; if given no arguments, it behaves like +@code{getservent} (see below). +@end deffn + +The following procedures may be used to step through the service +database from beginning to end. + +@deffn procedure setservent [stayopen] +Initialize an internal stream from which service objects may be read. This +procedure must be called before any calls to @code{getservent}, and may +also be called afterward to reset the service entry stream. If +@var{stayopen} is supplied and is not @code{#f}, the database is not +closed by subsequent @code{getservbyname} or @code{getservbyport} calls, +possibly giving an efficiency gain. +@end deffn + +@deffn procedure getservent +Return the next entry from the services database. +@end deffn + +@deffn procedure endservent +Close the stream used by @code{getservent}. The return value is unspecified. +@end deffn + +@deffn primitive setserv [stayopen] +If @var{stayopen} is omitted, this is equivalent to @code{endservent}. +Otherwise it is equivalent to @code{setservent stayopen}. +@end deffn + +@node Network Sockets and Communication +@subsection Network Sockets and Communication + +Socket ports can be created using @code{socket} and @code{socketpair}. +The ports are initially unbuffered, to make reading and writing to the +same port more reliable. A buffer can be added to the port using +@code{setvbuf}, @xref{Ports and File Descriptors}. + +The convention used for "host" vs "network" addresses is that addresses +are always held in host order at the Scheme level. The procedures in +this section automatically convert between host and network order when +required. The arguments and return values are thus in host order. + +@deffn primitive socket family style proto +Return a new socket port of the type specified by @var{family}, +@var{style} and @var{proto}. All three parameters are +integers. Supported values for @var{family} are +@code{AF_UNIX}, @code{AF_INET} and @code{AF_INET6}. +Typical values for @var{style} are @code{SOCK_STREAM}, +@code{SOCK_DGRAM} and @code{SOCK_RAW}. + +@var{proto} can be obtained from a protocol name using +@code{getprotobyname}. A value of zero specifies the default +protocol, which is usually right. + +A single socket port cannot by used for communication until it +has been connected to another socket. +@end deffn + +@deffn primitive socketpair family style proto +Return a pair of connected (but unnamed) socket ports of the +type specified by @var{family}, @var{style} and @var{proto}. +Many systems support only socket pairs of the @code{AF_UNIX} +family. Zero is likely to be the only meaningful value for +@var{proto}. +@end deffn + +@deffn primitive getsockopt sock level optname +Return the value of a particular socket option for the socket +port @var{sock}. @var{level} is an integer code for type of +option being requested, e.g., @code{SOL_SOCKET} for +socket-level options. @var{optname} is an integer code for the +option required and should be specified using one of the +symbols @code{SO_DEBUG}, @code{SO_REUSEADDR} etc. + +The returned value is typically an integer but @code{SO_LINGER} +returns a pair of integers. +@end deffn + +@deffn primitive setsockopt sock level optname value +Set the value of a particular socket option for the socket +port @var{sock}. @var{level} is an integer code for type of option +being set, e.g., @code{SOL_SOCKET} for socket-level options. +@var{optname} is an +integer code for the option to set and should be specified using one of +the symbols @code{SO_DEBUG}, @code{SO_REUSEADDR} etc. +@var{value} is the value to which the option should be set. For +most options this must be an integer, but for @code{SO_LINGER} it must +be a pair. + +The return value is unspecified. +@end deffn + +@deffn primitive shutdown sock how +Sockets can be closed simply by using @code{close-port}. The +@code{shutdown} procedure allows reception or tranmission on a +connection to be shut down individually, according to the parameter +@var{how}: + +@table @asis +@item 0 +Stop receiving data for this socket. If further data arrives, reject it. +@item 1 +Stop trying to transmit data from this socket. Discard any +data waiting to be sent. Stop looking for acknowledgement of +data already sent; don't retransmit it if it is lost. +@item 2 +Stop both reception and transmission. +@end table + +The return value is unspecified. +@end deffn + +@deffn primitive connect sock fam address . args +Initiate a connection from a socket using a specified address +family to the address +specified by @var{address} and possibly @var{args}. +The format required for @var{address} +and @var{args} depends on the family of the socket. + +For a socket of family @code{AF_UNIX}, +only @var{address} is specified and must be a string with the +filename where the socket is to be created. + +For a socket of family @code{AF_INET}, +@var{address} must be an integer IPv4 host address and +@var{args} must be a single integer port number. + +For a socket of family @code{AF_INET6}, +@var{address} must be an integer IPv6 host address and +@var{args} may be up to three integers: +port [flowinfo] [scope_id], +where flowinfo and scope_id default to zero. + +The return value is unspecified. +@end deffn + +@deffn primitive bind sock fam address . args +Assign an address to the socket port @var{sock}. +Generally this only needs to be done for server sockets, +so they know where to look for incoming connections. A socket +without an address will be assigned one automatically when it +starts communicating. + +The format of @var{address} and @var{args} depends +on the family of the socket. + +For a socket of family @code{AF_UNIX}, only @var{address} +is specified and must be a string with the filename where +the socket is to be created. + +For a socket of family @code{AF_INET}, @var{address} +must be an integer IPv4 address and @var{args} +must be a single integer port number. + +The values of the following variables can also be used for +@var{address}: + +@defvar INADDR_ANY +Allow connections from any address. +@end defvar + +@defvar INADDR_LOOPBACK +The address of the local host using the loopback device. +@end defvar + +@defvar INADDR_BROADCAST +The broadcast address on the local network. +@end defvar + +@defvar INADDR_NONE +No address. +@end defvar + +For a socket of family @code{AF_INET6}, @var{address} +must be an integer IPv6 address and @var{args} +may be up to three integers: +port [flowinfo] [scope_id], +where flowinfo and scope_id default to zero. + +The return value is unspecified. +@end deffn + +@deffn primitive listen sock backlog +Enable @var{sock} to accept connection +requests. @var{backlog} is an integer specifying +the maximum length of the queue for pending connections. +If the queue fills, new clients will fail to connect until +the server calls @code{accept} to accept a connection from +the queue. + +The return value is unspecified. +@end deffn + +@deffn primitive accept sock +Accept a connection on a bound, listening socket. +If there +are no pending connections in the queue, wait until +one is available unless the non-blocking option has been +set on the socket. + +The return value is a +pair in which the @emph{car} is a new socket port for the +connection and +the @emph{cdr} is an object with address information about the +client which initiated the connection. + +@var{sock} does not become part of the +connection and will continue to accept new requests. +@end deffn + +The following functions take a socket address object, as returned +by @code{accept} and other procedures, and return a selected component. + +@table @code +@item sockaddr:fam +The socket family, typically equal to the value of @code{AF_UNIX} or +@code{AF_INET}. +@item sockaddr:path +If the socket family is @code{AF_UNIX}, returns the path of the +filename the socket is based on. +@item sockaddr:addr +If the socket family is @code{AF_INET}, returns the Internet host +address. +@item sockaddr:port +If the socket family is @code{AF_INET}, returns the Internet port +number. +@end table + +@deffn primitive getsockname sock +Return the address of @var{sock}, in the same form as the +object returned by @code{accept}. On many systems the address +of a socket in the @code{AF_FILE} namespace cannot be read. +@end deffn + +@deffn primitive getpeername sock +Return the address that @var{sock} +is connected to, in the same form as the object returned by +@code{accept}. On many systems the address of a socket in the +@code{AF_FILE} namespace cannot be read. +@end deffn + +@deffn primitive recv! sock buf [flags] +Receive data from a socket port. +@var{sock} must already +be bound to the address from which data is to be received. +@var{buf} is a string into which +the data will be written. The size of @var{buf} limits +the amount of +data which can be received: in the case of packet +protocols, if a packet larger than this limit is encountered +then some data +will be irrevocably lost. + +The optional @var{flags} argument is a value or +bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc. + +The value returned is the number of bytes read from the +socket. + +Note that the data is read directly from the socket file +descriptor: +any unread buffered port data is ignored. +@end deffn + +@deffn primitive send sock message [flags] +Transmit the string @var{message} on a socket port @var{sock}. +@var{sock} must already be bound to a destination address. The +value returned is the number of bytes transmitted -- +it's possible for +this to be less than the length of @var{message} +if the socket is +set to be non-blocking. The optional @var{flags} argument +is a value or +bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc. + +Note that the data is written directly to the socket +file descriptor: +any unflushed buffered port data is ignored. +@end deffn + +@deffn primitive recvfrom! sock str [flags [start [end]]] +Return data from the socket port @var{sock} and also +information about where the data was received from. +@var{sock} must already be bound to the address from which +data is to be received. @code{str}, is a string into which the +data will be written. The size of @var{str} limits the amount +of data which can be received: in the case of packet protocols, +if a packet larger than this limit is encountered then some +data will be irrevocably lost. + +The optional @var{flags} argument is a value or bitwise OR of +@code{MSG_OOB}, @code{MSG_PEEK}, @code{MSG_DONTROUTE} etc. + +The value returned is a pair: the @emph{car} is the number of +bytes read from the socket and the @emph{cdr} an address object +in the same form as returned by @code{accept}. The address +will given as @code{#f} if not available, as is usually the +case for stream sockets. + +The @var{start} and @var{end} arguments specify a substring of +@var{str} to which the data should be written. + +Note that the data is read directly from the socket file +descriptor: any unread buffered port data is ignored. +@end deffn + +@deffn primitive sendto sock message fam address . args_and_flags +Transmit the string @var{message} on the socket port +@var{sock}. The +destination address is specified using the @var{fam}, +@var{address} and +@var{args_and_flags} arguments, in a similar way to the +@code{connect} procedure. @var{args_and_flags} contains +the usual connection arguments optionally followed by +a flags argument, which is a value or +bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc. + +The value returned is the number of bytes transmitted -- +it's possible for +this to be less than the length of @var{message} if the +socket is +set to be non-blocking. +Note that the data is written directly to the socket +file descriptor: +any unflushed buffered port data is ignored. +@end deffn + +The following functions can be used to convert short and long integers +between "host" and "network" order. Although the procedures above do +this automatically for addresses, the conversion will still need to +be done when sending or receiving encoded integer data from the network. + +@deffn primitive htons value +Convert a 16 bit quantity from host to network byte ordering. +@var{value} is packed into 2 bytes, which are then converted +and returned as a new integer. +@end deffn + +@deffn primitive ntohs value +Convert a 16 bit quantity from network to host byte ordering. +@var{value} is packed into 2 bytes, which are then converted +and returned as a new integer. +@end deffn + +@deffn primitive htonl value +Convert a 32 bit quantity from host to network byte ordering. +@var{value} is packed into 4 bytes, which are then converted +and returned as a new integer. +@end deffn + +@deffn primitive ntohl value +Convert a 32 bit quantity from network to host byte ordering. +@var{value} is packed into 4 bytes, which are then converted +and returned as a new integer. +@end deffn + +These procedures are inconvenient to use at present, but consider: + +@example +(define write-network-long + (lambda (value port) + (let ((v (make-uniform-vector 1 1 0))) + (uniform-vector-set! v 0 (htonl value)) + (uniform-vector-write v port)))) + +(define read-network-long + (lambda (port) + (let ((v (make-uniform-vector 1 1 0))) + (uniform-vector-read! v port) + (ntohl (uniform-vector-ref v 0))))) +@end example + +@node System Identification +@section System Identification + +This section lists the various procedures Guile provides for accessing +information about the system it runs on. + +@deffn primitive uname +Return an object with some information about the computer +system the program is running on. +@end deffn + +The following procedures accept an object as returned by @code{uname} +and return a selected component. + +@table @code +@item utsname:sysname +The name of the operating system. +@item utsname:nodename +The network name of the computer. +@item utsname:release +The current release level of the operating system implementation. +@item utsname:version +The current version level within the release of the operating system. +@item utsname:machine +A description of the hardware. +@end table + +@deffn primitive gethostname +Return the host name of the current processor. +@end deffn + +@deffn primitive sethostname name +Set the host name of the current processor to @var{name}. May +only be used by the superuser. The return value is not +specified. +@end deffn + +@c FIXME::martin: Not in libguile! +@deffn primitive software-type +Return a symbol describing the current platform's operating system. +This may be one of AIX, VMS, UNIX, COHERENT, WINDOWS, MS-DOS, OS/2, +THINKC, AMIGA, ATARIST, MACH, or ACORN. + +Note that most varieties of Unix are considered to be simply "UNIX". +That is because when a program depends on features that are not present +on every operating system, it is usually better to test for the presence +or absence of that specific feature. The return value of +@code{software-type} should only be used for this purpose when there is +no other easy or unambiguous way of detecting such features. +@end deffn + +@node Locales +@section Locales + +@deffn primitive setlocale category [locale] +If @var{locale} is omitted, return the current value of the +specified locale category as a system-dependent string. +@var{category} should be specified using the values +@code{LC_COLLATE}, @code{LC_ALL} etc. + +Otherwise the specified locale category is set to the string +@var{locale} and the new value is returned as a +system-dependent string. If @var{locale} is an empty string, +the locale will be set using envirionment variables. +@end deffn + +@node Encryption +@section Encryption + +Please note that the procedures in this section are not suited for +strong encryption, they are only interfaces to the well-known and +common system library functions of the same name. They are just as good +(or bad) as the underlying functions, so you should refer to your system +documentation before using them. + +@deffn primitive crypt key salt +Encrypt @var{key} using @var{salt} as the salt value to the +crypt(3) library call +@end deffn + +@code{getpass} is no encryption procedure at all, but it is often used +in compination with @code{crypt}, that is why it appears in this +section. + +@deffn primitive getpass prompt +Display @var{prompt} to the standard error output and read +a password from @file{/dev/tty}. If this file is not +accessible, it reads from standard input. The password may be +up to 127 characters in length. Additional characters and the +terminating newline character are discarded. While reading +the password, echoing and the generation of signals by special +characters is disabled. +@end deffn diff --git a/doc/ref/preface.texi b/doc/ref/preface.texi new file mode 100644 index 000000000..90e53e9ac --- /dev/null +++ b/doc/ref/preface.texi @@ -0,0 +1,182 @@ +@iftex +@page +@unnumbered Preface + +This reference manual documents Guile, GNU's Ubiquitous Intelligent +Language for Extensions. It describes how to use Guile in many useful +and interesting ways. + +This is edition 1.0 of the reference manual, and corresponds to Guile +version @value{VERSION}. +@end iftex + + +@iftex +@section The Guile License +@end iftex + +@ifnottex +@node Guile License +@chapter The Guile License +@end ifnottex + +The license of Guile consists of the GNU GPL plus a special statement +giving blanket permission to link with non-free software. This is the +license statement as found in any individual file that it applies to: + +@quotation +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this software; see the file COPYING. If not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA + +As a special exception, the Free Software Foundation gives permission +for additional uses of the text contained in its release of GUILE. + +The exception is that, if you link the GUILE library with other files to +produce an executable, this does not by itself cause the resulting +executable to be covered by the GNU General Public License. Your use of +that executable is in no way restricted on account of linking the GUILE +library code into it. + +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. + +This exception applies only to the code released by the Free Software +Foundation under the name GUILE. If you copy code from other Free +Software Foundation releases into a copy of GUILE, as the General Public +License permits, the exception does not apply to the code that you add +in this way. To avoid misleading anyone as to the status of such +modified files, you must delete this exception notice from them. + +If you write modifications of your own for GUILE, it is your choice +whether to permit this exception to apply to your modifications. If you +do not wish that, delete this exception notice. +@end quotation + + +@iftex +@section Layout of this Manual +@end iftex + +@ifnottex +@node Manual Layout +@chapter Layout of this Manual +@end ifnottex + +This manual is divided into five parts. + +@strong{Part I: Introduction to Guile} provides an overview of what +Guile is and how you can use it. A whirlwind tour shows how Guile can +be used interactively and as a script interpreter, how to link Guile +into your own applications, and how to write modules of interpreted and +compiled code for use with Guile. All of the ideas introduced here are +documented in full by the later parts of the manual. + +@strong{Part II: Guile Scheme} documents the core Scheme language and +features that Guile implements. Although the basis for this is the +Scheme language described in R5RS, this part of the manual does not +assume any prior familiarity with R5RS in particular, or with Scheme in +general. Basic Scheme concepts, standard aspects of the Scheme language +and Guile extensions on top of R5RS are all documented from scratch, and +organized by functionality rather than by the defining standards. + +@strong{Part III: Guile Modules} describes some important modules, +distributed as part of the Guile distribution, that extend the +functionality provided by the Guile Scheme core, most notably: + +@itemize @bullet +@item +the POSIX module, which provides Scheme level procedures for system and +network programming, conforming to the POSIX standard + +@item +the SLIB module, which makes Aubrey Jaffer's portable Scheme library +available for use in Guile. +@end itemize + +@strong{Part IV: Guile Scripting} documents the use of Guile as a script +interpreter, and illustrates this with a series of examples. + +@strong{Part V: Extending Applications Using Guile} explains the options +available for using Guile as a application extension language. At the +simpler end of the scale, an application might use Guile to define some +application-specific primitives in C and then load an application Scheme +file. In this case most of the application code is written on the +Scheme level, and uses the application-specific primitives as an +extension to standard Scheme. At the other end of the scale, an +application might be predominantly written in C --- with its main +control loop implemented in C --- but make occasional forays into Scheme +to, say, read configuration data or run user-defined customization code. +This part of the manual covers the complete range of application +extension options. + +Finally, the appendices explain how to obtain the latest version of +Guile, how to install it, where to find modules to work with Guile, and +how to use the Guile debugger. + + +@iftex +@section Manual Conventions +@end iftex + +@ifnottex +@node Manual Conventions +@chapter Conventions used in this Manual +@end ifnottex + +We use some conventions in this manual. + +@itemize @bullet + +@item +For some procedures, notably type predicates, we use @dfn{iff} to +mean `if and only if'. The construct is usually something like: +`Return @var{val} iff @var{condition}', where @var{val} is usually +`@code{#t}' or `non-@code{#f}'. This typically means that @var{val} +is returned if @var{condition} holds, and that @samp{#f} is returned +otherwise. +@cindex iff + +@item +In examples and procedure descriptions and all other places where the +evaluation of Scheme expression is shown, we use some notation for +denoting the output and evaluation results of expressions. + +The symbol @code{@result{}} is used to tell which value is returned by +an evaluation: + +@lisp +(+ 1 2) +@result{} +3 +@end lisp + +Some procedures produce some output besides returning a value. This +is denoted by the symbol @code{@print{}}. + +@lisp +(begin (display 1) (newline) 'hooray) +@print{} 1 +@result{} +hooray +@end lisp + +@c Add other conventions here. + +@end itemize + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/repl-modules.texi b/doc/ref/repl-modules.texi new file mode 100644 index 000000000..fdefbf755 --- /dev/null +++ b/doc/ref/repl-modules.texi @@ -0,0 +1,131 @@ +@page +@node Readline Support +@chapter Readline Support + +@c FIXME::martin: Review me! + +@cindex readline +@cindex command line history +Guile comes with an interface module to the readline library. This +makes interactive use much more convenient, because of the command-line +editing features of readline. Using @code{(ice-9 readline)}, you can +navigate through the current input line with the cursor keys, retrieve +older command lines from the input history and even search through the +history entries. + +@menu +* Loading Readline Support:: How to load readline support into Guile. +* Readline Options:: How to modify readline's behaviour. +@end menu + + +@node Loading Readline Support +@section Loading Readline Support + +The module is not loaded by default and so has to be loaded and +activated explicitly. This is done with two simple lines of code: + +@lisp +(use-modules (ice-9 readline)) +(activate-readline) +@end lisp + +@c FIXME::martin: Review me! + +The first line will load the necessary code, and the second will +activate readline's features for the REPL. If you plan to use this +module often, you should save these to lines to your @file{.guile} +personal startup file. + +You will notice that the REPL's behaviour changes a bit when you have +loaded the readline module. For examle, when you press Enter before +typing in the closing parentheses of a list, you will see the +@dfn{continuation} prompt, three dots: @code{...} This gives you a nice +visual feedback when trying to match parentheses. To make this even +easier, @dfn{bouncing parentheses} are implemented. That means that +when you type in a closing parentheses, the cursor will jump to the +corresponding opening paren for a short time, making it trivial to make +them match. + +Once the readline module is activated, all lines entered interactively +will be stored in a history and can be recalled later using the +cursor-up and -down keys. Readline also understands the Emacs keys for +navigating through the command line and history. + +When you quit your Guile session by evaluating @code{(quit)} or pressing +Ctrl-D, the history will be saved to the file @file{.guile_history} and +read in when you start Guile for the next time. Thus you can start a +new Guile session and still have the (probably long-winded) definition +expressions available. + + +@node Readline Options +@section Readline Options + +@c FIXME::martin: Review me! + +@cindex readline options +The readline interface module can be configured in several ways to +better suit the user's needs. Configuration is done via the readline +module's options interface, in a similar way to the evaluator and +debugging options (@pxref{General option interface}.) + +Here is the list of readline options generated by typing +@code{(readline-options 'full)} in Guile. You can also see the +default values. + +@smalllisp +bounce-parens 500 Time (ms) to show matching opening parenthesis (0 = off). +history-length 200 History length. +history-file yes Use history file. +@end smalllisp + +The history length specifies how many input lines will be remembered. +If the history contains that many lines and additional lines are +entered, the oldest lines will be lost. You can switch on/off the +usage of the history file using the following call. + +@lisp +(readline-disable 'history) +@end lisp + +The readline options interface can only be used @emph{after} loading +the readline module, because it is defined in that module. + + +@page +@node Value History +@chapter Value History + +@c FIXME::martin: Review me! + +@cindex value history +Another module which makes command line usage more convenient is +@code{(ice-9 history)}. This module will change the REPL so that each +value which is evaluated and printed will be remembered under a name +constructed from the dollar character (@code{$}) and the number of the +evaluated expression. + +Consider an example session. + +@example +guile> (use-modules (ice-9 history)) +guile> 1 +$1 = 1 +guile> (+ $1 $1) +$2 = 2 +guile> (* $2 $2) +$3 = 4 +@end example + +After loading the value history module @code{(ice-9 history)}, one +(trivial) expression is evaluated. The result is stored into the +variable @code{$1}. This fact is indicated by the output @code{$1 = }, +which is also caused by @code{(ice-9 history)}. In the next line, this +variable is used two times, to produce the value @code{$2}, which in +turn is used in the calculation for @code{$3}. + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-binding.texi b/doc/ref/scheme-binding.texi new file mode 100644 index 000000000..b37bced03 --- /dev/null +++ b/doc/ref/scheme-binding.texi @@ -0,0 +1,242 @@ +@page +@node Binding Constructs +@chapter 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 +@section Top Level Variable Definitions + +@c FIXME::martin: Review me! + +@cindex variable definition + +On the top level of a program (e.g. when not inside of a procedure +definition or a @code{let}, @code{let*} or @code{letrec} expression), a +definition of the form + +@lisp +(define a 1) +@end lisp + +@noindent +defines a variable called @var{a} and sets it to the value 1. When the +variable already was bound with a @code{define} expression, the above +form is completely equivalent to + +@lisp +(set! a 1) +@end lisp + +@noindent +that means that @code{define} can be used interchangeably with +@code{set!} when at the top level of the REPL or a Scheme source file. +But note that a @code{set!} is not allowed if the variable was not bound +before. + +Attention: definitions inside local binding constructs (@pxref{Local +Bindings}) act differently (@pxref{Internal Definitions}). + + +@node Local Bindings +@section 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 +@section 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 thogh 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 +@section Querying variable bindings + +Guile provides a procedure for checking wehther a symbol is bound in the +top level environment. If you want to test whether a symbol is locally +bound in expression, you can use the @code{bound?} macro from the module +@code{(ice-9 optargs)}, documented in @ref{Optional Arguments}. + +@c NJFIXME explain [env] +@deffn primitive defined? sym [env] +Return @code{#t} if @var{sym} is defined in the top-level environment. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-control.texi b/doc/ref/scheme-control.texi new file mode 100644 index 000000000..dd5f9be53 --- /dev/null +++ b/doc/ref/scheme-control.texi @@ -0,0 +1,823 @@ +@page +@node Control Mechanisms +@chapter Controlling the Flow of Program Execution + +@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. +@end menu + + +@node begin +@section Evaluating a Sequence of Expressions + +@c FIXME::martin: Review me! + +@c FIXME::martin: Maybe add examples? + +@cindex begin +@cindex sequencing +@cindex expression sequencing + +@code{begin} is used for grouping several expression together so that +they syntactically 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. +@end deffn + +@node if cond case +@section Simple Conditional Evaluation + +@c FIXME::martin: Review me! + +@c FIXME::martin: Maybe add examples? + +@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 ignoret. 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 keyword @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 epression(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 +@section Conditional Evaluation of a Sequence of Expressions + +@c FIXME::martin: Review me! + +@c FIXME::martin: Maybe add examples? + +@code{and} and @code{or} evaluate all their arguments, 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 +@section Iteration mechanisms + +@c FIXME::martin: Review me! + +@c FIXME::martin: Maybe add examples? + +@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 ((variable1 init1 step1) @dots{}) (test expr @dots{}) command @dots{} +The @var{init} expressions are evaluated and the @var{variables} are +bound to their values. Then looping starts with testing the @var{test} +expression. If @var{test} evaluates to a true value, the @var{expr} +following the @var{test} are evaluated and the value of the last +@var{expr} is returned as the value of the @code{do} expression. If +@var{test} evaluates to false, the @var{command}s are evaluated in +order, the @var{step}s are evaluated and stored into the @var{variables} +and the next iteration starts. + +Any of the @var{step} expressions may be omitted, so that the +corresponding variable is not changed during looping. +@end deffn + +@deffn syntax while cond body @dots{} +Evaluate all expressions in @var{body} in order, as long as @var{cond} +evaluates to a true value. The @var{cond} expression is tested before +every iteration, so that the body is not evaluated at all if @var{cond} +is @code{#f} right from the start. +@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 +@section Continuations + +@cindex call/cc +@cindex call-with-current-continuation +The ability to explicitly capture continuations using +@code{call-with-current-continuation} (also often called @code{call/cc} +for short), and to invoke such continuations later any number of times, +and from any other point in a program, provides maybe the most powerful +control structure known. All other control structures, such as loops +and coroutines, can be emulated using continuations. + +@c NJFIXME - need a little something here about what continuations are +@c and what they do for you. + +The implementation of continuations in Guile is not as efficient as one +might hope, because it is constrained by the fact that Guile is designed +to cooperate with programs written in other languages, such as C, which +do not know about continuations. So continuations should be used when +there is no other simple way of achieving the desired behaviour, or +where the advantages of the elegant continuation mechanism outweigh the +need for optimum performance. If you find yourself using @code{call/cc} +for escape procedures and your program is running too slow, you might +want to use exceptions (@pxref{Exceptions}) instead. + +@rnindex call-with-current-continuation +@deffn primitive call-with-current-continuation proc +Capture the current continuation and call @var{proc} with the captured +continuation as the single argument. This continuation can then be +called with arbitrarily many arguments. Such a call will work like a +goto to the invocation location of +@code{call-with-current-continuation}, passing the arguments in a way +that they are returned by the call to +@code{call-with-current-continuation}. Since it is legal to store the +captured continuation in a variable or to pass it to other procedures, +it is possible that a procedure returns more than once, even if it is +called only one time. This can be confusing at times. +@end deffn + +@c FIXME::martin: Better example needed. +@lisp +(define kont #f) +(call-with-current-continuation + (lambda (k) + (set! kont k) + 1)) +@result{} +1 + +(kont 2) +@result{} +2 +@end lisp + + +@node Multiple Values +@section Returning and Accepting Multiple Values + +@c FIXME::martin: Review me! +@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 +conceptionally 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 primitive values expr @dots{} +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. +@end deffn + +@rnindex call-with-values +@deffn primitive 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)) + ==> 5 + +@end example +@example +(call-with-values * -) ==> -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 +@section 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 +@subsection 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. (Especially +considering that Guile handles POSIX signals by throwing a corresponding +kind of exception: REFFIXME.) + +This manual prefers to speak of throwing and catching exceptions, since +this terminology matches the corresponding Guile primitives. + + +@node Catch +@subsection 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 @dfn{normal case} code --- i.e. what should +happen if no exceptions are thrown --- and a @dfn{handler} procedure +that says what to do if an exception is thrown. Note that if the +@dfn{normal case} thunk executes @dfn{normally}, which means without +throwing any exceptions, the handler procedure is not executed at all. + +When an exception is thrown using the @code{throw} primitive, 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 primitive 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. + + +@node Throw +@subsection 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 primitive 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 +@subsection 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 primitive 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 + +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 +@subsection 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 +@section 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 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 primitive scm-error 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 primitive 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 +@section Dynamic Wind + +[FIXME: this is pasted in from Tom Lord's original guile.texi and should +be reviewed] + +@rnindex dynamic-wind +@deffn primitive 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 +continuation of the @code{dynamic_wind} expression is escaped +non-locally, @var{out_guard} is called. If the continuation 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 +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-data.texi b/doc/ref/scheme-data.texi new file mode 100755 index 000000000..3303881ec --- /dev/null +++ b/doc/ref/scheme-data.texi @@ -0,0 +1,5230 @@ +@page +@node Data Types +@chapter Data Types for Generic Use + +This chapter describes all the data types that Guile provides for +``generic use''. + +One of the great strengths of Scheme is that there is no straightforward +distinction between ``data'' and ``functionality''. For example, +Guile's support for dynamic linking could be described + +@itemize @bullet +@item +either in a ``data-centric'' way, as the behaviour and properties of the +``dynamically linked object'' data type, and the operations that may be +applied to instances of this type + +@item +or in a ``functionality-centric'' way, as the set of procedures that +constitute Guile's support for dynamic linking, in the context of the +module system. +@end itemize + +The contents of this chapter are, therefore, a matter of judgement. By +``generic use'', we mean to select those data types whose typical use as +@emph{data} in a wide variety of programming contexts is more important +than their use in the implementation of a particular piece of +@emph{functionality}. + +@ifinfo +The following menu +@end ifinfo +@iftex +The table of contents for this chapter +@end iftex +@ifhtml +The following table of contents +@end ifhtml +shows the data types that are documented in this chapter. The final +section of this chapter lists all the core Guile data types that are not +documented here, and provides links to the ``functionality-centric'' +sections of this manual that cover them. + +@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 and Variables:: Manipulating the Scheme symbol table. +* Keywords:: Self-quoting, customizable display keywords. +* 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. +* Association Lists and Hash Tables:: Dictionary data types. +* Hooks:: User-customizable event lists. +* Other Data Types:: Data types that are documented elsewhere. +@end menu + + +@node Booleans +@section 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). + +The @code{not} procedure returns the boolean inverse of its argument: + +@rnindex not +@deffn primitive not x +Return @code{#t} iff @var{x} is @code{#f}, else return @code{#f}. +@end deffn + +The @code{boolean?} procedure is a predicate that returns @code{#t} if +its argument is one of the boolean values, otherwise @code{#f}. + +@rnindex boolean? +@deffn primitive boolean? obj +Return @code{#t} iff @var{obj} is either @code{#t} or @code{#f}. +@end deffn + + +@node Numbers +@section 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 +@xref{Numbers,,,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 +@subsection Scheme's Numerical ``Tower'' +@rnindex number? + +Scheme's numerical ``tower'' consists of the following categories of +numbers: + +@itemize @bullet +@item +integers (whole numbers) + +@item +rationals (the set of numbers that can be expressed as P/Q where P and Q +are integers) + +@item +real numbers (the set of numbers that describes all possible positions +along a one dimensional line) + +@item +complex numbers (the set of numbers that describes all possible +positions in a two dimensional space) +@end itemize + +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). + +Of these, Guile implements integers, reals and complex numbers as +distinct types. Rationals are implemented as regards the read syntax +for rational numbers that is specified by R5RS, but are immediately +converted by Guile to the corresponding real number. + +The @code{number?} predicate may be applied to any Scheme value to +discover whether the value is any of the supported numerical types. + +@deffn primitive number? obj +Return @code{#t} if @var{obj} is any kind of number, @code{#f} else. +@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 +@subsection Integers + +@tpindex Integer numbers + +@rnindex integer? + +Integers are whole numbers, that is numbers with no fractional part, +such as 2, 83 and -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. + +@c REFFIXME Maybe point here to discussion of handling immediates/bignums +@c on the C level, where the conversion is not so automatic - NJ + +@deffn primitive integer? x +Return @code{#t} if @var{x} is an integer number, @code{#f} else. + +@lisp +(integer? 487) +@result{} +#t + +(integer? -3.4) +@result{} +#f +@end lisp +@end deffn + + +@node Reals and Rationals +@subsection 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 P/Q, where P and 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 represents both real and rational numbers approximately using a +floating point encoding with limited precision. Even though the actual +encoding 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, +@code{-0.00000142857931198} is the same as @code{142857931198} divided by +@code{100000000000000000}. In Guile's current incarnation, therefore, +the @code{rational?} and @code{real?} predicates are equivalent. + +Another aspect of this equivalence is that Guile currently does not +preserve the exactness that is possible with rational arithmetic. +If such exactness is needed, it is of course possible to implement +exact rational arithmetic at the Scheme level using Guile's arbitrary +size integers. + +A planned future revision of Guile's numerical tower will make it +possible to implement exact representations and arithmetic for both +rational numbers and real irrational numbers such as square roots, +and in such a way that the new kinds of number integrate seamlessly +with those that are already implemented. + +@deffn primitive real? obj +Return @code{#t} if @var{obj} is a real number, @code{#f} else. +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 primitive rational? x +Return @code{#t} if @var{x} is a rational number, @code{#f} +else. 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. Real numbers +will also satisfy this predicate, because of their limited +precision. +@end deffn + + +@node Complex Numbers +@subsection 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 as a pair of numbers both of which are +real, so the real and imaginary parts of a complex number have the same +properties of inexactness and limited precision as single real numbers. + +@deffn primitive complex? x +Return @code{#t} if @var{x} is a complex number, @code{#f} +else. 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 +@subsection 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 @code{5} and the +corresponding inexact real value which, to the limited precision +available, has no fractional part, and is printed as @code{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 primitive exact? x +Return @code{#t} if @var{x} is an exact number, @code{#f} +otherwise. +@end deffn + +@deffn primitive inexact? x +Return @code{#t} if @var{x} is an inexact number, @code{#f} +else. +@end deffn + +@deffn primitive inexact->exact z +Return an exact number that is numerically closest to @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "exact->inexact") +@deffn primitive exact->inexact z +Convert the number @var{z} to its inexact representation. +@end deffn + + +@node Number Syntax +@subsection 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: + +@itemize @bullet +@item +@code{#b}, @code{#B} --- the integer is written in binary (base 2) + +@item +@code{#o}, @code{#O} --- the integer is written in octal (base 8) + +@item +@code{#d}, @code{#D} --- the integer is written in decimal (base 10) + +@item +@code{#x}, @code{#X} --- the integer is written in hexadecimal (base 16). +@end itemize + +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: + +@itemize @bullet +@item +@code{#e}, @code{#E} --- the number is exact + +@item +@code{#i}, @code{#I} --- the number is inexact. +@end itemize + +If the exactness indicator is omitted, the integer is assumed to be exact, +since Guile's internal representation for integers is always exact. +Real numbers have limited precision similar to the precision of the +@code{double} type in C. A consequence of the limited precision is that +all real numbers in Guile are also rational, since any number R with a +limited number of decimal places, say N, can be made into an integer by +multiplying by 10^N. + + +@node Integer Operations +@subsection Operations on Integer Values +@rnindex odd? +@rnindex even? +@rnindex quotient +@rnindex remainder +@rnindex modulo +@rnindex gcd +@rnindex lcm + +@deffn primitive odd? n +Return @code{#t} if @var{n} is an odd number, @code{#f} +otherwise. +@end deffn + +@deffn primitive even? n +Return @code{#t} if @var{n} is an even number, @code{#f} +otherwise. +@end deffn + +@c begin (texi-doc-string "guile" "quotient") +@deffn primitive quotient +Return the quotient of the numbers @var{x} and @var{y}. +@end deffn + +@c begin (texi-doc-string "guile" "remainder") +@deffn primitive remainder +Return the remainder of the numbers @var{x} and @var{y}. +@lisp +(remainder 13 4) @result{} 1 +(remainder -13 4) @result{} -1 +@end lisp +@end deffn + +@c begin (texi-doc-string "guile" "modulo") +@deffn primitive modulo +Return the modulo of the numbers @var{x} and @var{y}. +@lisp +(modulo 13 4) @result{} 1 +(modulo -13 4) @result{} 3 +@end lisp +@end deffn + +@c begin (texi-doc-string "guile" "gcd") +@deffn primitive gcd +Return the greatest common divisor of all arguments. +If called without arguments, 0 is returned. +@end deffn + +@c begin (texi-doc-string "guile" "lcm") +@deffn primitive lcm +Return the least common multiple of the arguments. +If called without arguments, 1 is returned. +@end deffn + + +@node Comparison +@subsection Comparison Predicates +@rnindex zero? +@rnindex positive? +@rnindex negative? + +@c begin (texi-doc-string "guile" "=") +@deffn primitive = +Return @code{#t} if all parameters are numerically equal. +@end deffn + +@c begin (texi-doc-string "guile" "<") +@deffn primitive < +Return @code{#t} if the list of parameters is monotonically +increasing. +@end deffn + +@c begin (texi-doc-string "guile" ">") +@deffn primitive > +Return @code{#t} if the list of parameters is monotonically +decreasing. +@end deffn + +@c begin (texi-doc-string "guile" "<=") +@deffn primitive <= +Return @code{#t} if the list of parameters is monotonically +non-decreasing. +@end deffn + +@c begin (texi-doc-string "guile" ">=") +@deffn primitive >= +Return @code{#t} if the list of parameters is monotonically +non-increasing. +@end deffn + +@c begin (texi-doc-string "guile" "zero?") +@deffn primitive zero? +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 primitive positive? +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 primitive negative? +Return @code{#t} if @var{x} is an exact or inexact number less than +zero. +@end deffn + + +@node Conversion +@subsection Converting Numbers To and From Strings +@rnindex number->string +@rnindex string->number + +@deffn primitive number->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 primitive string->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 +@subsection Complex Number Operations +@rnindex make-rectangular +@rnindex make-polar +@rnindex real-part +@rnindex imag-part +@rnindex magnitude +@rnindex angle + +@deffn primitive make-rectangular real imaginary +Return a complex number constructed of the given @var{real} and +@var{imaginary} parts. +@end deffn + +@deffn primitive 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 primitive real-part +Return the real part of the number @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "imag-part") +@deffn primitive imag-part +Return the imaginary part of the number @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "magnitude") +@deffn primitive magnitude +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 primitive angle +Return the angle of the complex number @var{z}. +@end deffn + + +@node Arithmetic +@subsection Arithmetic Functions +@rnindex max +@rnindex min +@rnindex + +@rnindex * +@rnindex - +@rnindex / +@rnindex abs +@rnindex floor +@rnindex ceiling +@rnindex truncate +@rnindex round + +@c begin (texi-doc-string "guile" "+") +@deffn primitive + z1 @dots{} +Return the sum of all parameter values. Return 0 if called without any +parameters. +@end deffn + +@c begin (texi-doc-string "guile" "-") +@deffn primitive - z1 z2 @dots{} +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 primitive * z1 @dots{} +Return the product of all arguments. If called without arguments, 1 is +returned. +@end deffn + +@c begin (texi-doc-string "guile" "/") +@deffn primitive / z1 z2 @dots{} +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 primitive abs x +Return the absolute value of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "max") +@deffn primitive max x1 x2 @dots{} +Return the maximum of all parameter values. +@end deffn + +@c begin (texi-doc-string "guile" "min") +@deffn primitive min x1 x2 @dots{} +Return the minium of all parameter values. +@end deffn + +@c begin (texi-doc-string "guile" "truncate") +@deffn primitive truncate +Round the inexact number @var{x} towards zero. +@end deffn + +@c begin (texi-doc-string "guile" "round") +@deffn primitive round x +Round the inexact number @var{x} towards zero. +@end deffn + +@c begin (texi-doc-string "guile" "floor") +@deffn primitive floor x +Round the number @var{x} towards minus infinity. +@end deffn + +@c begin (texi-doc-string "guile" "ceiling") +@deffn primitive ceiling x +Round the number @var{x} towards infinity. +@end deffn + + +@node Scientific +@subsection 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 procedure sqrt z +Return the square root of @var{z}. +@end deffn + +@rnindex expt +@c begin (texi-doc-string "guile" "expt") +@deffn 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 procedure sin z +Return the sine of @var{z}. +@end deffn + +@rnindex cos +@c begin (texi-doc-string "guile" "cos") +@deffn procedure cos z +Return the cosine of @var{z}. +@end deffn + +@rnindex tan +@c begin (texi-doc-string "guile" "tan") +@deffn procedure tan z +Return the tangent of @var{z}. +@end deffn + +@rnindex asin +@c begin (texi-doc-string "guile" "asin") +@deffn procedure asin z +Return the arcsine of @var{z}. +@end deffn + +@rnindex acos +@c begin (texi-doc-string "guile" "acos") +@deffn procedure acos z +Return the arccosine of @var{z}. +@end deffn + +@rnindex atan +@c begin (texi-doc-string "guile" "atan") +@deffn procedure atan z +Return the arctangent of @var{z}. +@end deffn + +@rnindex exp +@c begin (texi-doc-string "guile" "exp") +@deffn 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 procedure log z +Return the natural logarithm of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "log10") +@deffn procedure log10 z +Return the base 10 logarithm of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "sinh") +@deffn procedure sinh z +Return the hyperbolic sine of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "cosh") +@deffn procedure cosh z +Return the hyperbolic cosine of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "tanh") +@deffn procedure tanh z +Return the hyperbolic tangent of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "asinh") +@deffn procedure asinh z +Return the hyperbolic arcsine of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "acosh") +@deffn procedure acosh z +Return the hyperbolic arccosine of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "atanh") +@deffn procedure atanh z +Return the hyperbolic arctangent of @var{z}. +@end deffn + + +@node Primitive Numerics +@subsection 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 primitive $abs x +Return the absolute value of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$sqrt") +@deffn primitive $sqrt x +Return the square root of @var{x}. +@end deffn + +@deffn primitive $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 primitive $sin x +Return the sine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$cos") +@deffn primitive $cos x +Return the cosine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$tan") +@deffn primitive $tan x +Return the tangent of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$asin") +@deffn primitive $asin x +Return the arcsine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$acos") +@deffn primitive $acos x +Return the arccosine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$atan") +@deffn primitive $atan x +Return the arctangent of @var{x} in the range -PI/2 to PI/2. +@end deffn + +@deffn primitive $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 primitive $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 primitive $log x +Return the natural logarithm of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$sinh") +@deffn primitive $sinh x +Return the hyperbolic sine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$cosh") +@deffn primitive $cosh x +Return the hyperbolic cosine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$tanh") +@deffn primitive $tanh x +Return the hyperbolic tangent of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$asinh") +@deffn primitive $asinh x +Return the hyperbolic arcsine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$acosh") +@deffn primitive $acosh x +Return the hyperbolic arccosine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$atanh") +@deffn primitive $atanh x +Return the hyperbolic arctangent of @var{x}. +@end deffn + + +@node Bitwise Operations +@subsection Bitwise Operations + +@deffn primitive logand n1 n2 +Return the integer which is the bit-wise AND of the two integer +arguments. + +@lisp +(number->string (logand #b1100 #b1010) 2) + @result{} "1000" +@end lisp +@end deffn + +@deffn primitive logior n1 n2 +Return the integer which is the bit-wise OR of the two integer +arguments. + +@lisp +(number->string (logior #b1100 #b1010) 2) + @result{} "1110" +@end lisp +@end deffn + +@deffn primitive logxor n1 n2 +Return the integer which is the bit-wise XOR of the two integer +arguments. + +@lisp +(number->string (logxor #b1100 #b1010) 2) + @result{} "110" +@end lisp +@end deffn + +@deffn primitive lognot n +Return the integer which is the 2s-complement of the integer +argument. + +@lisp +(number->string (lognot #b10000000) 2) + @result{} "-10000001" +(number->string (lognot #b0) 2) + @result{} "-1" +@end lisp +@end deffn + +@deffn primitive 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 primitive logbit? 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 primitive ash n cnt +The function ash performs an arithmetic shift left by @var{cnt} +bits (or shift right, if @var{cnt} is negative). 'Arithmetic' +means, that the function does not guarantee to keep the bit +structure of @var{n}, but rather guarantees that the result +will always be rounded towards minus infinity. Therefore, the +results of ash and a corresponding bitwise shift will differ if +@var{n} is negative. + +Formally, the function returns an integer equivalent to +@code{(inexact->exact (floor (* @var{n} (expt 2 @var{cnt}))))}. + +@lisp +(number->string (ash #b1 3) 2) @result{} "1000" +(number->string (ash #b1010 -1) 2) @result{} "101" +@end lisp +@end deffn + +@deffn primitive 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 primitive integer-length n +Return the number of bits neccessary to represent @var{n}. + +@lisp +(integer-length #b10101010) + @result{} 8 +(integer-length 0) + @result{} 0 +(integer-length #b1111) + @result{} 4 +@end lisp +@end deffn + +@deffn primitive 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 primitive 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 +@subsection Random Number Generation + +@deffn primitive copy-random-state [state] +Return a copy of the random state @var{state}. +@end deffn + +@deffn primitive random n [state] +Return a number in [0,N). + +Accepts a positive integer or real n and returns a +number of the same type between zero (inclusive) and +N (exclusive). The values returned have a uniform +distribution. + +The optional argument @var{state} must be of the type produced +by @code{seed->random-state}. It defaults to the value of the +variable @var{*random-state*}. This object is used to maintain +the state of the pseudo-random-number generator and is altered +as a side effect of the random operation. +@end deffn + +@deffn primitive random:exp [state] +Return an inexact real in an exponential distribution with mean +1. For an exponential distribution with mean u use (* u +(random:exp)). +@end deffn + +@deffn primitive random:hollow-sphere! v [state] +Fills vect with inexact real random numbers +the sum of whose squares is equal to 1.0. +Thinking of vect as coordinates in space of +dimension n = (vector-length vect), the coordinates +are uniformly distributed over the surface of the +unit n-shere. +@end deffn + +@deffn primitive 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 m and standard deviation d use +@code{(+ m (* d (random:normal)))}. +@end deffn + +@deffn primitive random:normal-vector! v [state] +Fills vect with inexact real random numbers that are +independent and standard normally distributed +(i.e., with mean 0 and variance 1). +@end deffn + +@deffn primitive random:solid-sphere! v [state] +Fills vect with inexact real random numbers +the sum of whose squares is less than 1.0. +Thinking of vect as coordinates in space of +dimension n = (vector-length vect), the coordinates +are uniformly distributed within the unit n-shere. +The sum of the squares of the numbers is returned. +@end deffn + +@deffn primitive random:uniform [state] +Return a uniformly distributed inexact real random number in +[0,1). +@end deffn + +@deffn primitive seed->random-state seed +Return a new random state using @var{seed}. +@end deffn + + +@node Characters +@section Characters +@tpindex Characters + +Most of the characters in the ASCII character set may be referred to by +name: for example, @code{#\tab}, @code{#\esc}, @code{#\stx}, and so on. +The following table describes the 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 @code{delete} character (octal 177) may be referred to with the name +@code{#\del}. + +Several characters have more than one name: + +@itemize @bullet +@item +@code{#\space}, @code{#\sp} +@item +@code{#\newline}, @code{#\nl} +@item +@code{#\tab}, @code{#\ht} +@item +@code{#\backspace}, @code{#\bs} +@item +@code{#\return}, @code{#\cr} +@item +@code{#\page}, @code{#\np} +@item +@code{#\null}, @code{#\nul} +@end itemize + +@rnindex char? +@deffn primitive char? x +Return @code{#t} iff @var{x} is a character, else @code{#f}. +@end deffn + +@rnindex char=? +@deffn primitive char=? x y +Return @code{#t} iff @var{x} is the same character as @var{y}, else @code{#f}. +@end deffn + +@rnindex char<? +@deffn primitive char<? x y +Return @code{#t} iff @var{x} is less than @var{y} in the ASCII sequence, +else @code{#f}. +@end deffn + +@rnindex char<=? +@deffn primitive char<=? x y +Return @code{#t} iff @var{x} is less than or equal to @var{y} in the +ASCII sequence, else @code{#f}. +@end deffn + +@rnindex char>? +@deffn primitive char>? x y +Return @code{#t} iff @var{x} is greater than @var{y} in the ASCII +sequence, else @code{#f}. +@end deffn + +@rnindex char>=? +@deffn primitive char>=? x y +Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the +ASCII sequence, else @code{#f}. +@end deffn + +@rnindex char-ci=? +@deffn primitive 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 primitive char-ci<? x y +Return @code{#t} iff @var{x} is less than @var{y} in the ASCII sequence +ignoring case, else @code{#f}. +@end deffn + +@rnindex char-ci<=? +@deffn primitive char-ci<=? x y +Return @code{#t} iff @var{x} is less than or equal to @var{y} in the +ASCII sequence ignoring case, else @code{#f}. +@end deffn + +@rnindex char-ci>? +@deffn primitive char-ci>? x y +Return @code{#t} iff @var{x} is greater than @var{y} in the ASCII +sequence ignoring case, else @code{#f}. +@end deffn + +@rnindex char-ci>=? +@deffn primitive char-ci>=? x y +Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the +ASCII sequence ignoring case, else @code{#f}. +@end deffn + +@rnindex char-alphabetic? +@deffn primitive char-alphabetic? chr +Return @code{#t} iff @var{chr} is alphabetic, else @code{#f}. +Alphabetic means the same thing as the isalpha C library function. +@end deffn + +@rnindex char-numeric? +@deffn primitive char-numeric? chr +Return @code{#t} iff @var{chr} is numeric, else @code{#f}. +Numeric means the same thing as the isdigit C library function. +@end deffn + +@rnindex char-whitespace? +@deffn primitive char-whitespace? chr +Return @code{#t} iff @var{chr} is whitespace, else @code{#f}. +Whitespace means the same thing as the isspace C library function. +@end deffn + +@rnindex char-upper-case? +@deffn primitive char-upper-case? chr +Return @code{#t} iff @var{chr} is uppercase, else @code{#f}. +Uppercase means the same thing as the isupper C library function. +@end deffn + +@rnindex char-lower-case? +@deffn primitive char-lower-case? chr +Return @code{#t} iff @var{chr} is lowercase, else @code{#f}. +Lowercase means the same thing as the islower C library function. +@end deffn + +@deffn primitive char-is-both? chr +Return @code{#t} iff @var{chr} is either uppercase or lowercase, else @code{#f}. +Uppercase and lowercase are as defined by the isupper and islower +C library functions. +@end deffn + +@rnindex char->integer +@deffn primitive char->integer chr +Return the number corresponding to ordinal position of @var{chr} in the +ASCII sequence. +@end deffn + +@rnindex integer->char +@deffn primitive integer->char n +Return the character at position @var{n} in the ASCII sequence. +@end deffn + +@rnindex char-upcase +@deffn primitive char-upcase chr +Return the uppercase character version of @var{chr}. +@end deffn + +@rnindex char-downcase +@deffn primitive char-downcase chr +Return the lowercase character version of @var{chr}. +@end deffn + + +@node Strings +@section 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 REPL or in Scheme source files. + +Guile provides a rich set of string processing procedures, because text +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 NUL character @code{'\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 unusal 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. +* String Miscellanea:: Miscellaneous string procedures. +@end menu + +@node String Syntax +@subsection String Read Syntax + +The read syntax for strings is an arbitrarily long sequence of +characters enclosed in double quotes (@code{"}). @footnote{Actually, the +current implementation restricts strings to a length of 2^24 +characters.} If you want to insert a double quote character into a +string literal, it must be prefixed with a backslash @code{\} character +(called an @emph{escape character}). + +The following are examples of string literals: + +@lisp +"foo" +"bar plonk" +"Hello World" +"\"Hi\", he said." +@end lisp + +@c FIXME::martin: What about escape sequences like \r, \n etc.? + +@node String Predicates +@subsection String Predicates + +The following procedures can be used to check whether a given string +fulfills some specified property. + +@rnindex string? +@deffn primitive string? obj +Return @code{#t} iff @var{obj} is a string, else returns +@code{#f}. +@end deffn + +@deffn primitive string-null? str +Return @code{#t} if @var{str}'s length is nonzero, and +@code{#f} otherwise. +@lisp +(string-null? "") @result{} #t +y @result{} "foo" +(string-null? y) @result{} #f +@end lisp +@end deffn + +@node String Constructors +@subsection 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 primitive string . chrs +@deffnx primitive list->string chrs +Return a newly allocated string composed of the arguments, +@var{chrs}. +@end deffn + +@rnindex make-string +@deffn primitive 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 +@subsection 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 primitive string->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 primitive 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 +@subsection 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 primitive string-length string +Return the number of characters in @var{string}. +@end deffn + +@rnindex string-ref +@deffn primitive 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 primitive string-copy str +Return a newly allocated copy of the given @var{string}. +@end deffn + +@rnindex substring +@deffn primitive 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} <= (string-length @var{str}). +@end deffn + +@node String Modification +@subsection String Modification + +These procedures are for modifying strings in-place. That means, that +not a new string is the result of a string operation, but that the +actual memory representation of a string is modified. + +@rnindex string-set! +@deffn primitive string-set! 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 primitive string-fill! str chr +Store @var{char} in every element of the given @var{string} and +return an unspecified value. +@end deffn + +@deffn primitive substring-fill! 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 primitive substring-move! str1 start1 end1 str2 start2 +@deffnx primitive substring-move-left! str1 start1 end1 str2 start2 +@deffnx primitive substring-move-right! 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{end2}. +@code{substring-move-right!} begins copying from the rightmost character +and moves left, and @code{substring-move-left!} copies from the leftmost +character moving right. + +It is useful to have two functions that copy in different directions so +that substrings can be copied back and forth within a single string. If +you wish to copy text from the left-hand side of a string to the +right-hand side of the same string, and the source and destination +overlap, you must be careful to copy the rightmost characters of the +text first, to avoid clobbering your data. Hence, when @var{str1} and +@var{str2} are the same string, you should use +@code{substring-move-right!} when moving text from left to right, and +@code{substring-move-left!} otherwise. If @code{str1} and @samp{str2} +are different strings, it does not matter which function you use. + +@example +(define x (make-string 10 #\a)) +(define y "bcd") +(substring-move-left! x 2 5 y 0) +y +@result{} "aaa" + +x +@result{} "aaaaaaaaaa" + +(define y "bcdefg") +(substring-move-left! x 2 5 y 0) +y +@result{} "aaaefg" + +(define y "abcdefg") +(substring-move-left! y 2 5 y 3) +y +@result{} "abccccg" + +(define y "abcdefg") +(substring-move-right! y 2 5 y 0) +y +@result{} "ededefg" + +(define y "abcdefg") +(substring-move-right! y 2 5 y 3) +y +@result{} "abccdeg" +@end example +@end deffn + + +@node String Comparison +@subsection 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 primitive 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 primitive string<? s1 s2 +Lexicographic ordering predicate; return @code{#t} if @var{s1} +is lexicographically less than @var{s2}. +@end deffn + +@rnindex string<=? +@deffn primitive 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 primitive string>? s1 s2 +Lexicographic ordering predicate; return @code{#t} if @var{s1} +is lexicographically greater than @var{s2}. +@end deffn + +@rnindex string>=? +@deffn primitive 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 primitive 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 primitive 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 primitive 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 primitive 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 primitive 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 +@subsection String Searching + +When searching the index of a character in a string, these procedures +can be used. + +@deffn primitive 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 primitive 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 +@subsection Alphabetic Case Mapping + +These are procedures for mapping strings to their upper- or lower-case +equivalents, respectively, or for capitalizing strings. + +@deffn primitive string-upcase str +Return a freshly allocated string containing the characters of +@var{str} in upper case. +@end deffn + +@deffn primitive string-upcase! 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 primitive string-downcase str +Return a freshly allocation string containing the characters in +@var{str} in lower case. +@end deffn + +@deffn primitive string-downcase! 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 primitive 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 primitive string-capitalize! 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 +@subsection Appending Strings + +The procedure @code{string-append} appends several strings together to +form a longer result string. + +@rnindex string-append +@deffn primitive string-append string1 @dots{} +Return a newly allocated string whose characters form the +concatenation of the given strings. +@end deffn + + +@node String Miscellanea +@subsection String Miscellanea + +This section contains all remaining string procedures. + +@deffn primitive string-ci->symbol str +Return the symbol whose name is @var{str}. @var{str} is +converted to lowercase before the conversion is done, if Guile +is currently reading symbols case-insensitively. +@end deffn + + +@node Regular Expressions +@section 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 the +@code{*features*} list includes the @code{regex} symbol. + +@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 metacharacters. +* Rx Interface:: Tom Lord's Rx library does things differently. +@end menu + +[FIXME: it may be useful to include an Examples section. Parts of this +interface are bewildering on first glance.] + +@node Regexp Functions +@subsection 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. + +@c begin (scm-doc-string "regex.scm" "string-match") +@deffn 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 + +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 primitive make-regexp pat . flags +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{flags} arguments change the behavior of the compiled +regular expression. The following flags may be supplied: + +@table @code +@item regexp/icase +Consider uppercase and lowercase letters to be the same when +matching. +@item 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. +@item 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. +@item 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 table +@end deffn + +@deffn primitive 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. +@end deffn + +@deffn primitive regexp? 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 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 + +@var{port} 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 + +@c begin (scm-doc-string "regex.scm" "regexp-substitute") +@deffn 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 @var{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 + +@node Match Structures +@subsection 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 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 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 + +@c begin (scm-doc-string "regex.scm" "match:start") +@deffn procedure match:start match [n] +Return the starting position of submatch number @var{n}. +@end deffn + +@c begin (scm-doc-string "regex.scm" "match:end") +@deffn procedure match:end match [n] +Return the ending position of submatch number @var{n}. +@end deffn + +@c begin (scm-doc-string "regex.scm" "match:prefix") +@deffn procedure match:prefix match +Return the unmatched portion of @var{target} preceding the regexp match. +@end deffn + +@c begin (scm-doc-string "regex.scm" "match:suffix") +@deffn procedure match:suffix match +Return the unmatched portion of @var{target} following the regexp match. +@end deffn + +@c begin (scm-doc-string "regex.scm" "match:count") +@deffn 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 procedure match:string match +Return the original @var{target} string. +@end deffn + +@node Backslash Escapes +@subsection 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 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 Rx Interface +@subsection Rx Interface + +@c FIXME::martin: Shouldn't this be removed or moved to the +@c ``Guile Modules'' chapter? The functions are not available in +@c plain Guile... + +[FIXME: this is taken from Gary and Mark's quick summaries and should be +reviewed and expanded. Rx is pretty stable, so could already be done!] + +@cindex rx +@cindex finite automaton + +Guile includes an interface to Tom Lord's Rx library (currently only to +POSIX regular expressions). Use of the library requires a two step +process: compile a regular expression into an efficient structure, then +use the structure in any number of string comparisons. + +For example, given the +regular expression @samp{abc.} (which matches any string containing +@samp{abc} followed by any single character): + +@smalllisp +guile> @kbd{(define r (regcomp "abc."))} +guile> @kbd{r} +#<rgx abc.> +guile> @kbd{(regexec r "abc")} +#f +guile> @kbd{(regexec r "abcd")} +#((0 . 4)) +guile> +@end smalllisp + +The definitions of @code{regcomp} and @code{regexec} are as follows: + +@c NJFIXME not in libguile! +@deffn primitive regcomp pattern [flags] +Compile the regular expression pattern using POSIX rules. Flags is +optional and should be specified using symbolic names: +@defvar REG_EXTENDED +use extended POSIX syntax +@end defvar +@defvar REG_ICASE +use case-insensitive matching +@end defvar +@defvar REG_NEWLINE +allow anchors to match after newline characters in the +string and prevents @code{.} or @code{[^...]} from matching newlines. +@end defvar + +The @code{logior} procedure can be used to combine multiple flags. +The default is to use +POSIX basic syntax, which makes @code{+} and @code{?} literals and @code{\+} +and @code{\?} +operators. Backslashes in @var{pattern} must be escaped if specified in a +literal string e.g., @code{"\\(a\\)\\?"}. +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive regexec regex string [match-pick] [flags] + +Match @var{string} against the compiled POSIX regular expression +@var{regex}. +@var{match-pick} and @var{flags} are optional. Possible flags (which can be +combined using the logior procedure) are: + +@defvar REG_NOTBOL +The beginning of line operator won't match the beginning of +@var{string} (presumably because it's not the beginning of a line) +@end defvar + +@defvar REG_NOTEOL +Similar to REG_NOTBOL, but prevents the end of line operator +from matching the end of @var{string}. +@end defvar + +If no match is possible, regexec returns #f. Otherwise @var{match-pick} +determines the return value: + +@code{#t} or unspecified: a newly-allocated vector is returned, +containing pairs with the indices of the matched part of @var{string} and any +substrings. + +@code{""}: a list is returned: the first element contains a nested list +with the matched part of @var{string} surrounded by the the unmatched parts. +Remaining elements are matched substrings (if any). All returned +substrings share memory with @var{string}. + +@code{#f}: regexec returns #t if a match is made, otherwise #f. + +vector: the supplied vector is returned, with the first element replaced +by a pair containing the indices of the matched portion of @var{string} and +further elements replaced by pairs containing the indices of matched +substrings (if any). + +list: a list will be returned, with each member of the list +specified by a code in the corresponding position of the supplied list: + +a number: the numbered matching substring (0 for the entire match). + +@code{#\<}: the beginning of @var{string} to the beginning of the part matched +by regex. + +@code{#\>}: the end of the matched part of @var{string} to the end of +@var{string}. + +@code{#\c}: the "final tag", which seems to be associated with the "cut +operator", which doesn't seem to be available through the posix +interface. + +e.g., @code{(list #\< 0 1 #\>)}. The returned substrings share memory with +@var{string}. +@end deffn + +Here are some other procedures that might be used when using regular +expressions: + +@c NJFIXME not in libguile! +@deffn primitive compiled-regexp? obj +Test whether obj is a compiled regular expression. +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive regexp->dfa regex [flags] +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive dfa-fork dfa +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive reset-dfa! dfa +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive dfa-final-tag dfa +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive dfa-continuable? dfa +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive advance-dfa! dfa string +@end deffn + + +@node Symbols and Variables +@section Symbols and Variables + +@c FIXME::martin: Review me! + +Symbols are a data type with a special property. On the one hand, +symbols are used for denoting variables in a Scheme program, on the +other they can be used as literal data as well. + +The association between symbols and values is maintained in special data +structures, the symbol tables. + +In addition, Guile offers variables as first-class objects. They can +be used for interacting with the module system. + +@menu +* Symbols:: All about symbols as a data type. +* Symbol Tables:: Tables for mapping symbols to values. +* Variables:: First-class variables. +@end menu + +@node Symbols +@subsection Symbols +@tpindex Symbols + +@c FIXME::martin: Review me! + +Symbols are especially useful because two symbols which are spelled the +same way are equivalent in the sense of @code{eq?}. That means that +they are actually the same Scheme object. The advantage is that symbols +can be compared extremely efficiently, although they carry more +information for the human reader than, say, numbers. + +It is very common in Scheme programs to use symbols as keys in +association lists (@pxref{Association Lists}) or hash tables +(@pxref{Hash Tables}), because this usage improves the readability a +lot, and does not cause any performance loss. + +The read syntax for symbols is a sequence of letters, digits, and +@emph{extended alphabetic characters} that begins with a character that +cannot begin a number is an identifier. In addition, @code{+}, +@code{-}, and @code{...} are identifiers. + +Extended alphabetic characters may be used within identifiers as if +they were letters. The following are extended alphabetic characters: + +@example +! $ % & * + - . / : < = > ? @@ ^ _ ~ +@end example + +In addition to the read syntax defined above (which is taken from R5RS +(@pxref{Formal syntax,,,r5rs,The Revised^5 Report on Scheme})), Guile +provides a method for writing symbols with unusual characters, such as +space characters. If you (for whatever reason) need to write a symbol +containing characters not mentioned above, you write symbols as follows: + +@itemize @bullet +@item +Begin the symbol with the two character @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 +containing a space character, the second containing a line break and the +last one looks like a number. + +@lisp +#@{foo bar@}# +#@{what +ever@}# +#@{4242@}# +@end lisp + +Usage of this form of read syntax is discouraged, because it is not +portable at all, and is not very readable. + +@rnindex symbol? +@deffn primitive symbol? obj +Return @code{#t} if @var{obj} is a symbol, otherwise return +@code{#f}. +@end deffn + +@rnindex string->symbol +@deffn primitive string->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. See +@code{symbol->string}. + +The following examples assume that the implementation's +standard case is lower case: + +@lisp +(eq? 'mISSISSIppi 'mississippi) @result{} #t +(string->symbol "mISSISSIppi") @result{} @r{the symbol with name "mISSISSIppi"} +(eq? 'bitBlt (string->symbol "bitBlt")) @result{} #f +(eq? 'JollyWog + (string->symbol (symbol->string 'JollyWog))) @result{} #t +(string=? "K. Harper, M.D." + (symbol->string + (string->symbol "K. Harper, M.D."))) @result{}#t +@end lisp +@end deffn + +@rnindex symbol->string +@deffn primitive symbol->string s +Return the name of @var{symbol} as a string. If the symbol was +part of an object returned as the value of a literal expression +(section @pxref{Literal expressions,,,r5rs, The Revised^5 +Report on Scheme}) or by a call to the @code{read} procedure, +and its name contains alphabetic characters, then the string +returned will contain characters in the implementation's +preferred standard case--some implementations will prefer +upper case, others lower case. If the symbol was returned by +@code{string->symbol}, the case of characters in the string +returned will be the same as the case in the string that was +passed to @code{string->symbol}. It is an error to apply +mutation procedures like @code{string-set!} to strings returned +by this procedure. + +The following examples assume that the implementation's +standard case is lower case: + +@lisp +(symbol->string 'flying-fish) @result{} "flying-fish" +(symbol->string 'Martin) @result{} "martin" +(symbol->string + (string->symbol "Malvina")) @result{} "Malvina" +@end lisp +@end deffn + +@node Symbol Tables +@subsection Symbol Tables + +@c FIXME::martin: Review me! + +@c FIXME::martin: Are all these procedures still relevant? + +Guile symbol tables are hash tables. Each hash table, also called an +@dfn{obarray} (for `object array'), is a vector of association lists. +Each entry in the alists is a pair (@var{SYMBOL} . @var{VALUE}). To +@dfn{intern} a symbol in a symbol table means to return its +(@var{SYMBOL} . @var{VALUE}) pair, adding a new entry to the symbol +table (with an undefined value) if none is yet present. + +@c FIXME::martin: According to NEWS, removed. Remove here too, or +@c leave for compatibility? +@c @c docstring begin (texi-doc-string "guile" "builtin-bindings") +@c @deffn primitive builtin-bindings +@c Create and return a copy of the global symbol table, removing all +@c unbound symbols. +@c @end deffn + +@deffn primitive 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 @code{g}. The counter +is increased by 1 at each call. There is no provision for +resetting the counter. +@end deffn + +@deffn primitive gentemp [prefix [obarray]] +Create a new symbol with a name unique in an obarray. +The name is constructed from an optional string @var{prefix} +and a counter value. The default prefix is @code{t}. The +@var{obarray} is specified as a second optional argument. +Default is the system obarray where all normal symbols are +interned. The counter is increased by 1 at each +call. There is no provision for resetting the counter. +@end deffn + +@deffn primitive intern-symbol obarray string +Add a new symbol to @var{obarray} with name @var{string}, bound to an +unspecified initial value. The symbol table is not modified if a symbol +with this name is already present. +@end deffn + +@deffn primitive string->obarray-symbol obarray string [soft?] +Intern a new symbol in @var{obarray}, a symbol table, with name +@var{string}. +@end deffn + +@deffn primitive symbol-binding obarray string +Look up in @var{obarray} the symbol whose name is @var{string}, and +return the value to which it is bound. If @var{obarray} is @code{#f}, +use the global symbol table. If @var{string} is not interned in +@var{obarray}, an error is signalled. +@end deffn + +@deffn primitive symbol-bound? obarray string +Return @code{#t} if @var{obarray} contains a symbol with name +@var{string} bound to a defined value. This differs from +@var{symbol-interned?} in that the mere mention of a symbol +usually causes it to be interned; @code{symbol-bound?} +determines whether a symbol has been given any meaningful +value. +@end deffn + +@deffn primitive symbol-fref symbol +Return the contents of @var{symbol}'s @dfn{function slot}. +@end deffn + +@deffn primitive symbol-fset! symbol value +Change the binding of @var{symbol}'s function slot. +@end deffn + +@deffn primitive symbol-hash symbol +Return a hash value for @var{symbol}. +@end deffn + +@deffn primitive symbol-interned? obarray string +Return @code{#t} if @var{obarray} contains a symbol with name +@var{string}, and @code{#f} otherwise. +@end deffn + +@deffn primitive symbol-pref symbol +Return the @dfn{property list} currently associated with @var{symbol}. +@end deffn + +@deffn primitive symbol-pset! symbol value +Change the binding of @var{symbol}'s property slot. +@end deffn + +@deffn primitive symbol-set! obarray string value +Find the symbol in @var{obarray} whose name is @var{string}, and rebind +it to @var{value}. An error is signalled if @var{string} is not present +in @var{obarray}. +@end deffn + +@deffn primitive unintern-symbol obarray string +Remove the symbol with name @var{string} from @var{obarray}. This +function returns @code{#t} if the symbol was present and @code{#f} +otherwise. +@end deffn + +@node Variables +@subsection Variables +@tpindex Variables + +@c FIXME::martin: Review me! + +Variables are objects with two fields. They contain a value and they +can contain a symbol, which is the name of the variable. A variable is +said to be bound if it does not contain the object denoting unbound +variables in the value slot. + +Variables do not have a read syntax, they have to be created by calling +one of the constructor procedures @code{make-variable} or +@code{make-undefined-variable} or retrieved by @code{builtin-variable}. + +First-class variables are especially useful for interacting with the +current module system (@pxref{The Guile module system}). + +@deffn primitive builtin-variable name +Return the built-in variable with the name @var{name}. +@var{name} must be a symbol (not a string). +Then use @code{variable-ref} to access its value. +@end deffn + +@deffn primitive make-undefined-variable [name-hint] +Return a variable object initialized to an undefined value. +If given, uses @var{name-hint} as its internal (debugging) +name, otherwise just treat it as an anonymous variable. +Remember, of course, that multiple bindings to the same +variable may exist, so @var{name-hint} is just that---a hint. +@end deffn + +@deffn primitive make-variable init [name-hint] +Return a variable object initialized to value @var{init}. +If given, uses @var{name-hint} as its internal (debugging) +name, otherwise just treat it as an anonymous variable. +Remember, of course, that multiple bindings to the same +variable may exist, so @var{name-hint} is just that---a hint. +@end deffn + +@deffn primitive variable-bound? 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 primitive 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 primitive variable-set! 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 primitive variable? obj +Return @code{#t} iff @var{obj} is a variable object, else +return @code{#f} +@end deffn + + +@node Keywords +@section 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? +@subsection 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 +colour depth -- Default: the colour depth for the screen + +@item +background colour -- 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 ;; Colour depth + 'default ;; Background colour + 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 +@subsection 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, @ref{Optional +Arguments}. + + +@node Keyword Read Syntax +@subsection 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, 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-options} procedure documented in @ref{General option +interface} and @ref{Reader options}. + +@smalllisp +(read-set! keywords 'prefix) + +#:type +@result{} +#:type + +:type +@result{} +#:type + +(read-set! keywords #f) + +#:type +@result{} +#:type + +:type +@result{} +ERROR: In expression :type: +ERROR: Unbound variable: :type +ABORT: (unbound-variable) +@end smalllisp + +@node Keyword Procedures +@subsection Keyword Procedures + +@c FIXME::martin: Review me! + +The following procedures can be used for converting symbols to keywords +and back. + +@deffn procedure symbol->keyword sym +Return a keyword with the same characters as in @var{sym}. +@end deffn + +@deffn procedure keyword->symbol kw +Return a symbol with the same characters as in @var{kw}. +@end deffn + + +@node Keyword Primitives +@subsection 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 primitive make-keyword-from-dash-symbol symbol +Make a keyword object from a @var{symbol} that starts with a dash. +@end deffn + +@deffn primitive keyword? obj +Return @code{#t} if the argument @var{obj} is a keyword, else +@code{#f}. +@end deffn + +@deffn primitive keyword-dash-symbol keyword +Return the dash symbol for @var{keyword}. +This is the inverse of @code{make-keyword-from-dash-symbol}. +@end deffn + +@node Pairs +@section Pairs +@tpindex Pairs + +@c FIXME::martin: Review me! + +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 @emph{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 whould 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 +@emph{construct}. Use the procedure @code{pair?} to test whether a +given Scheme object is a pair or not. + +@rnindex cons +@deffn primitive 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 primitive pair? 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 @emph{car} and +@emph{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 primitive car pair +@deffnx primitive cdr pair +Return the car or the cdr of @var{pair}, respectively. +@end deffn + +@deffn primitive caar pair +@deffnx primitive cadr pair @dots{} +@deffnx primitive cdddar pair +@deffnx primitive 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 primitive set-car! 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 primitive set-cdr! 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 +@section Lists +@tpindex Lists + +@c FIXME::martin: Review me! + +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 @emph{list}. Lists are made up of +chained @emph{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 Modifification:: Modifying list structure. +* List Searching:: Searching for list elements +* List Mapping:: Applying procedures to lists. +@end menu + +@node List Syntax +@subsection List Read Syntax + +@c FIXME::martin: Review me! + +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 +@subsection List Predicates + +@c FIXME::martin: Review me! + +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 primitive list? 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, teh algorithm terminates. + +@rnindex null? +@deffn primitive null? x +Return @code{#t} iff @var{x} is the empty list, else @code{#f}. +@end deffn + +@node List Constructors +@subsection 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. + +@rnindex list +@deffn primitive list arg1 @dots{} +Return a list containing @var{objs}, the arguments to +@code{list}. +@end deffn + +@deffn primitive 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 primitive list-copy lst +Return a (newly-created) copy of @var{lst}. +@end deffn + +@deffn 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 modyfies 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 +@subsection List Selection + +@c FIXME::martin: Review me! + +These procedures are used to get some information about a list, or to +retrieve one or more elements of a list. + +@rnindex length +@deffn primitive length lst +Return the number of elements in list @var{lst}. +@end deffn + +@deffn primitive 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 primitive list-ref list k +Return the @var{k}th element from @var{list}. +@end deffn + +@rnindex list-tail +@deffn primitive list-tail lst k +@deffnx primitive list-cdr-ref 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 primitive 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 +@subsection Append and Reverse + +@c FIXME::martin: Review me! + +@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 primitive append . args +Return a list consisting of the elements the lists passed as +arguments. +@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 resulting list is always newly allocated, except that it +shares structure with the last list argument. The last +argument 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 +@end deffn + +@deffn primitive append! . lists +A destructive version of @code{append} (@pxref{Pairs and +lists,,,r5rs, The Revised^5 Report on Scheme}). The cdr field +of each list's final pair is changed to point to the head of +the next list, so no consing is performed. Return a pointer to +the mutated list. +@end deffn + +@rnindex reverse +@deffn primitive reverse lst +Return a new list that contains the elements of @var{lst} but +in reverse order. +@end deffn + +@c NJFIXME explain new_tail +@deffn primitive reverse! lst [new_tail] +A destructive version of @code{reverse} (@pxref{Pairs and lists,,,r5rs, +The Revised^5 Report on Scheme}). The cdr of each cell in @var{lst} is +modified to point to the previous list element. Return a pointer to the +head of the reversed list. + +Caveat: because the list is modified in place, the tail of the original +list now becomes its head, and the head of the original list now becomes +the tail. Therefore, the @var{lst} symbol to which the head of the +original list was bound now points to the tail. To ensure that the head +of the modified list is not lost, it is wise to save the return value of +@code{reverse!} +@end deffn + +@node List Modifification +@subsection List Modification + +@c FIXME::martin: Review me! + +The following procedures modify existing list. @code{list-set!} and +@code{list-cdr-set!} change which elements a list contains, the various +deletion procedures @code{delq}, @code{delv} etc. + +@deffn primitive list-set! list k val +Set the @var{k}th element of @var{list} to @var{val}. +@end deffn + +@deffn primitive list-cdr-set! list k val +Set the @var{k}th cdr of @var{list} to @var{val}. +@end deffn + +@deffn primitive 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 primitive 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 primitive 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 primitive delq! item lst +@deffnx primitive delv! item lst +@deffnx primitive delete! 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 primitive delq1! 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 primitive delv1! 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 primitive delete1! 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 + +@node List Searching +@subsection List Searching + +@c FIXME::martin: Review me! + +The following procedures search lists for particular elements. They use +different comparison predicates for comparing list elements with the +object to be seached. 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 primitive 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 primitive 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 primitive 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 + +[FIXME: is there any reason to have the `sloppy' functions available at +high level at all? Maybe these docs should be relegated to a "Guile +Internals" node or something. -twp] + +@deffn primitive sloppy-memq x lst +This procedure behaves like @code{memq}, but does no type or error checking. +Its use is recommended only in writing Guile internals, +not for high-level Scheme programs. +@end deffn + +@deffn primitive sloppy-memv x lst +This procedure behaves like @code{memv}, but does no type or error checking. +Its use is recommended only in writing Guile internals, +not for high-level Scheme programs. +@end deffn + +@deffn primitive sloppy-member x lst +This procedure behaves like @code{member}, but does no type or error checking. +Its use is recommended only in writing Guile internals, +not for high-level Scheme programs. +@end deffn + +@node List Mapping +@subsection List Mapping + +@c FIXME::martin: Review me! + +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 what +the result of the invocation is. + +@rnindex map +@c begin (texi-doc-string "guile" "map") +@deffn primitive map proc arg1 arg2 @dots{} +@deffnx primitive map-in-order proc arg1 arg2 @dots{} +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 primitive 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 +@section Vectors +@tpindex Vectors + +@c FIXME::martin: Review me! + +@c FIXME::martin: Should the subsections of this section be nodes +@c of their own, or are the resulting nodes too short, then? + +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 is constant, whereas lists have an access time linear to the +index of the accessed element in the list. + +Note that the vectors documented in this section can contain any kind of +Scheme object, it is even possible to have different types of objects in +the same vector. + +@subsection Vector Read Syntax + +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 hexidecimal notation. + +@lisp +#(1 2 3) +#("Hello" foo #xdeadbeef) +@end lisp + +@subsection Vector Predicates + +@rnindex vector? +@deffn primitive vector? obj +Return @code{#t} if @var{obj} is a vector, otherwise return +@code{#f}. +@end deffn + +@subsection Vector Constructors + +@rnindex make-vector +@deffn primitive make-vector k [fill] +Return a newly allocated vector of @var{k} elements. If a +second argument is given, then each element is initialized to +@var{fill}. Otherwise the initial contents of each element is +unspecified. +@end deffn + +@rnindex vector +@rnindex list->vector +@deffn primitive vector . l +@deffnx primitive list->vector l +Return a newly allocated vector whose elements contain the +given arguments. Analogous to @code{list}. + +@lisp +(vector 'a 'b 'c) @result{} #(a b c) +@end lisp +@end deffn + +@rnindex vector->list +@deffn primitive vector->list v +Return a newly allocated list of the objects contained in the +elements of @var{vector}. + +@lisp +(vector->list '#(dah dah didah)) @result{} (dah dah didah) +(list->vector '(dididit dah)) @result{} #(dididit dah) +@end lisp +@end deffn + +@subsection Vector Modification + +A vector created by any of the vector constructor procedures +(@pxref{Vectors}) documented above can be modified using the +following procedures. + +According to R5RS, using any of these procedures on literally entered +vectors is an error, because these vectors are considered to be +constant, although Guile currently does not detect this error. + +@rnindex vector-set! +@deffn primitive vector-set! vector k obj +@var{k} must be a valid index of @var{vector}. +@code{Vector-set!} stores @var{obj} in element @var{k} 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") +(vector-set! '#(0 1 2) 1 "doe") @result{} @emph{error} ; constant vector +@end lisp +@end deffn + +@rnindex vector-fill! +@deffn primitive vector-fill! v fill +Store @var{fill} in every element of @var{vector}. The value +returned by @code{vector-fill!} is unspecified. +@end deffn + +@deffn primitive vector-move-left! vec1 start1 end1 vec2 start2 +Vector version of @code{substring-move-left!}. +@end deffn + +@deffn primitive vector-move-right! vec1 start1 end1 vec2 start2 +Vector version of @code{substring-move-right!}. +@end deffn + +@subsection Vector Selection + +These procedures return information about a given vector, such as the +size or what elements are contained in the vector. + +@rnindex vector-length +@deffn primitive vector-length vector +Returns the number of elements in @var{vector} as an exact integer. +@end deffn + +@rnindex vector-ref +@deffn primitive vector-ref vector k +@var{k} must be a valid index of @var{vector}. +@samp{Vector-ref} returns the contents of element @var{k} 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 + + +@node Records +@section Records + +[FIXME: this is pasted in from Tom Lord's original guile.texi and should +be reviewed] + +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 procedure record? obj +Returns @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 procedure make-record-type type-name field-names +Returns 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.@refill +@end deffn + +@deffn procedure record-constructor rtd [field-names] +Returns 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.@refill +@end deffn + +@deffn procedure record-predicate rtd +Returns 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.@refill +@end deffn + +@deffn procedure record-accessor rtd field-name +Returns 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}.@refill +@end deffn + +@deffn procedure record-modifier rtd field-name +Returns 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}.@refill +@end deffn + +@deffn procedure record-type-descriptor record +Returns 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.@refill +@end deffn + +@deffn procedure record-type-name rtd +Returns 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}.@refill +@end deffn + +@deffn procedure record-type-fields rtd +Returns 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}.@refill +@end deffn + + +@node Structures +@section 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 +@subsection 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 specifiy 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 +@subsection 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 malloced 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 @emph{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 conventioal +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 primitive 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 +@subsection Structure Basics + +This section describes the basic procedures for creating and accessing +structures. + +@deffn primitive 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 primitive struct? x +Return @code{#t} iff @var{obj} is a structure object, else +@code{#f}. +@end deffn + + +@deffn primitive struct-ref handle pos +@deffnx primitive struct-set! 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 +@subsection 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 primitive struct-vtable handle +Return the vtable structure that describes the type of @var{struct}. +@end deffn + +@deffn primitive struct-vtable? x +Return @code{#t} iff obj 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 primitive 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 primitive struct-vtable-name vtable +Return the name of the vtable @var{vtable}. +@end deffn + +@deffn primitive set-struct-vtable-name! vtable name +Set the name of the vtable @var{vtable} to @var{name}. +@end deffn + +@deffn primitive struct-vtable-tag handle +Return the vtable tag of the structure @var{handle}. +@end deffn + + +@node Arrays +@section 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 +@subsection Conventional Arrays + +@dfn{Conventional arrays} are a collection of cells organised 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, and 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, organised into dimensions +using parentheses. The nesting depth of the parentheses is equal to +the rank. + +When an array is created, the number of dimensions and range of each +dimension must be specified, e.g., to create a 2x3 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). + +@deffn primitive array? v [prot] +Return @code{#t} if the @var{obj} is an array, and @code{#f} if +not. The @var{prototype} argument is used with uniform arrays +and is described elsewhere. +@end deffn + +@deffn procedure make-array initial-value bound1 bound2 @dots{} +Creates and returns an array that has as many dimensions as there are +@var{bound}s and fills it with @var{initial-value}. +@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 primitive uniform-vector-ref v args +@deffnx primitive array-ref v . args +Return the element at the @code{(index1, index2)} element in +@var{array}. +@end deffn + +@deffn primitive array-in-bounds? v . args +Return @code{#t} if its arguments would be acceptable to +@code{array-ref}. +@end deffn + +@deffn primitive array-set! v obj . args +@deffnx primitive uniform-array-set1! v obj args +Sets the element at the @code{(index1, index2)} element in @var{array} to +@var{new-value}. The value returned by array-set! is unspecified. +@end deffn + +@deffn primitive make-shared-array oldra mapfunc . dims +@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 primitive shared-array-increments ra +For each dimension, return the distance between elements in the root vector. +@end deffn + +@deffn primitive shared-array-offset ra +Return the root vector index of the first element in the array. +@end deffn + +@deffn primitive shared-array-root ra +Return the root vector of a shared array. +@end deffn + +@deffn primitive transpose-array ra . args +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{dim0}, @var{dim1}, @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{dim0}, @var{dim1}, @dots{} correspond to +dimensions in the array to be returned, 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 primitive enclose-array ra . axes +@var{dim0}, @var{dim1} @dots{} should be nonnegative integers less than +the rank of @var{array}. @var{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 @var{array-prototype} when given an +enclosed array is unspecified. + +examples: +@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 procedure array-shape array +Returns a list of inclusive bounds of integers. +@example +(array-shape (make-array 'foo '(-1 3) 5)) @result{} ((-1 3) (0 4)) +@end example +@end deffn + +@deffn primitive array-dimensions ra +@code{Array-dimensions} is similar to @code{array-shape} but replaces +elements with a @code{0} minimum with one greater than the maximum. So: +@lisp +(array-dimensions (make-array 'foo '(-1 3) 5)) @result{} ((-1 3) 5) +@end lisp +@end deffn + +@deffn primitive array-rank ra +Return the number of dimensions of @var{obj}. If @var{obj} is +not an array, @code{0} is returned. +@end deffn + +@deffn primitive array->list v +Return a list consisting of all the elements, in order, of +@var{array}. +@end deffn + +@deffn primitive array-copy! src dst +@deffnx primitive array-copy-in-order! src dst +Copies every element from vector or array @var{source} to the +corresponding element of @var{destination}. @var{destination} must have +the same rank as @var{source}, and be at least as large in each +dimension. The order is unspecified. +@end deffn + +@deffn primitive array-fill! ra fill +Stores @var{fill} in every element of @var{array}. The value returned +is unspecified. +@end deffn + +@c begin (texi-doc-string "guile" "array-equal?") +@deffn primitive array-equal? ra0 ra1 +Returns @code{#t} iff 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 primitive array-contents ra [strict] +@deffnx primitive 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 @var{make-array} and +@var{make-uniform-array} may be unrolled, some arrays made by +@var{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 +@subsection Array Mapping + +@deffn primitive array-map! ra0 proc . lra +@deffnx primitive array-map-in-order! ra0 proc . lra +@var{array1}, @dots{} must have the same number of dimensions as +@var{array0} and have a range for each index which includes the range +for the corresponding index in @var{array0}. @var{proc} is applied to +each tuple of elements of @var{array1} @dots{} and the result is stored +as the corresponding element in @var{array0}. The value returned is +unspecified. The order of application is unspecified. +@end deffn + +@deffn primitive array-for-each proc ra0 . lra +@var{proc} is applied to each tuple of elements of @var{array0} @dots{} +in row-major order. The value returned is unspecified. +@end deffn + +@deffn primitive array-index-map! ra proc +applies @var{proc} to the indices of each element of @var{array} in +turn, storing the result in the corresponding element. The value +returned and the order of application are unspecified. + +One can implement @var{array-indexes} as +@lisp +(define (array-indexes array) + (let ((ra (apply make-array #f (array-shape array)))) + (array-index-map! ra (lambda x x)) + ra)) +@end lisp +Another example: +@lisp +(define (apl:index-generator n) + (let ((v (make-uniform-vector n 1))) + (array-index-map! v (lambda (i) i)) + v)) +@end lisp +@end deffn + +@node Uniform Arrays +@subsection 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 + +@noindent +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 primitive array? v [prot] +Returns @code{#t} if the @var{obj} is an array, and @code{#f} if not. + +The @var{prototype} argument is used with uniform arrays and is described +elsewhere. +@end deffn + +@deffn procedure make-uniform-array prototype bound1 bound2 @dots{} +Creates and returns a uniform array of type corresponding to +@var{prototype} that has as many dimensions as there are @var{bound}s +and fills it with @var{prototype}. +@end deffn + +@deffn primitive 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 primitive list->uniform-array ndim prot lst +@deffnx procedure list->uniform-vector 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 primitive uniform-vector-fill! uve fill +Stores @var{fill} in every element of @var{uve}. The value returned is +unspecified. +@end deffn + +@deffn primitive uniform-vector-length v +Return the number of elements in @var{uve}. +@end deffn + +@deffn primitive dimensions->uniform-array dims prot [fill] +@deffnx primitive make-uniform-vector length prototype [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 primitive uniform-array-read! ra [port_or_fd [start [end]]] +@deffnx primitive uniform-vector-read! uve [port-or-fdes] [start] [end] +Attempts 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 during +uniform-array-read! the objects up to that point only 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 primitive uniform-array-write v [port_or_fd [start [end]]] +@deffnx primitive uniform-vector-write uve [port-or-fdes] [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 +@subsection 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 + +#b(#t #f #t) @result{} +#*101 +@end example + +@deffn primitive bit-count b bitvector +Return the number of occurrences of the boolean @var{b} in +@var{bitvector}. +@end deffn + +@deffn primitive bit-position item v k +Return the minimum index of an occurrence of @var{bool} in +@var{bv} which is at least @var{k}. If no @var{bool} occurs +within the specified range @code{#f} is returned. +@end deffn + +@deffn primitive bit-invert! v +Modifies @var{bv} by replacing each element with its negation. +@end deffn + +@deffn primitive bit-set*! v kv obj +If uve is a bit-vector @var{bv} and uve must be of the same +length. If @var{bool} is @code{#t}, uve is OR'ed into +@var{bv}; If @var{bool} is @code{#f}, the inversion of uve is +AND'ed into @var{bv}. + +If uve is a unsigned long integer vector all the elements of uve +must be between 0 and the @code{length} of @var{bv}. The bits +of @var{bv} corresponding to the indexes in uve are set to +@var{bool}. The return value is unspecified. +@end deffn + +@deffn primitive bit-count* v kv obj +Return +@lisp +(bit-count (bit-set*! (if bool bv (bit-invert! bv)) uve #t) #t). +@end lisp +@var{bv} is not modified. +@end deffn + + +@node Association Lists and Hash Tables +@section Association Lists and Hash Tables + +This chapter discusses dictionary objects: data structures that are +useful for organizing and indexing large bodies of information. + +@menu +* Dictionary Types:: About dictionary types; what they're good for. +* Association Lists:: List-based dictionaries. +* Hash Tables:: Table-based dictionaries. +@end menu + +@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 primitive acons key value alist +Adds 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 primitive assq-set! alist key val +@deffnx primitive assv-set! alist key value +@deffnx primitive assoc-set! alist key value +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 primitive assq key alist +@deffnx primitive assv key alist +@deffnx primitive assoc key alist +Fetches 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 @code{#f} is returned. 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 primitive assq-ref alist key +@deffnx primitive assv-ref alist key +@deffnx primitive 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 primitive assq-remove! alist key +@deffnx primitive assv-remove! alist key +@deffnx primitive assoc-remove! 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 NULLP): "open sesame" +ABORT: (wrong-type-arg) + +(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 CONSP): 2 +ABORT: (wrong-type-arg) + +(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 primitive 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 primitive 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 primitive 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" "Bismarck")) +capitals +@result{} (("South Dakota" . "Bismarck") + ("New York" . "Albany") + ("Oregon" . "Salem") + ("Florida" . "Miami")) + +;; And we got Florida wrong. +(set! capitals + (assoc-set! capitals "Florida" "Tallahassee")) +capitals +@result{} (("South Dakota" . "Bismarck") + ("New York" . "Albany") + ("Oregon" . "Salem") + ("Florida" . "Tallahassee")) + +;; After Oregon secedes, we can remove it. +(set! capitals + (assoc-remove! capitals "Oregon")) +capitals +@result{} (("South Dakota" . "Bismarck") + ("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 + +Like the association list functions, the hash table functions come +in several varieties: @code{hashq}, @code{hashv}, and @code{hash}. +The @code{hashq} functions use @code{eq?} to determine whether two +keys match. The @code{hashv} functions use @code{eqv?}, and the +@code{hash} functions use @code{equal?}. + +In each of the functions that follow, the @var{table} argument +must be a vector. The @var{key} and @var{value} arguments may be +any Scheme object. + +@deffn procedure make-hash-table size +Create a new hash table of @var{size} slots. Note that the number of +slots does not limit the size of the table, it just tells how large +the underlying vector will be. The @var{size} should be similar to +the expected number of elements which will be added to the table, but +they need not match. For good performance, it might be a good idea to +use a prime number as the @var{size}. +@end deffn + +@deffn primitive hashq-ref table key [dflt] +Look up @var{key} in the hash table @var{table}, and return the +value (if any) associated with it. If @var{key} is not found, +return @var{default} (or @code{#f} if no @var{default} argument +is supplied). Uses @code{eq?} for equality testing. +@end deffn + +@deffn primitive hashv-ref table key [dflt] +Look up @var{key} in the hash table @var{table}, and return the +value (if any) associated with it. If @var{key} is not found, +return @var{default} (or @code{#f} if no @var{default} argument +is supplied). Uses @code{eqv?} for equality testing. +@end deffn + +@deffn primitive hash-ref table key [dflt] +Look up @var{key} in the hash table @var{table}, and return the +value (if any) associated with it. If @var{key} is not found, +return @var{default} (or @code{#f} if no @var{default} argument +is supplied). Uses @code{equal?} for equality testing. +@end deffn + +@deffn primitive hashq-set! table key val +Find the entry in @var{table} associated with @var{key}, and +store @var{value} there. Uses @code{eq?} for equality testing. +@end deffn + +@deffn primitive hashv-set! table key val +Find the entry in @var{table} associated with @var{key}, and +store @var{value} there. Uses @code{eqv?} for equality testing. +@end deffn + +@deffn primitive hash-set! table key val +Find the entry in @var{table} associated with @var{key}, and +store @var{value} there. Uses @code{equal?} for equality +testing. +@end deffn + +@deffn primitive hashq-remove! table key +Remove @var{key} (and any value associated with it) from +@var{table}. Uses @code{eq?} for equality tests. +@end deffn + +@deffn primitive hashv-remove! table key +Remove @var{key} (and any value associated with it) from +@var{table}. Uses @code{eqv?} for equality tests. +@end deffn + +@deffn primitive hash-remove! table key +Remove @var{key} (and any value associated with it) from +@var{table}. Uses @code{equal?} for equality tests. +@end deffn + +The standard hash table functions may be too limited for some +applications. For example, you may want a hash table to store +strings in a case-insensitive manner, so that references to keys +named ``foobar'', ``FOOBAR'' and ``FooBaR'' will all yield the +same item. Guile provides you with @dfn{extended} hash tables +that permit you to specify a hash function and associator function +of your choosing. The functions described in the rest of this section +can be used to implement such custom hash table structures. + +If you are unfamiliar with the inner workings of hash tables, then +this facility will probably be a little too abstract for you to +use comfortably. If you are interested in learning more, see an +introductory textbook on data structures or algorithms for an +explanation of how hash tables are implemented. + +@deffn primitive hashq key size +Determine a hash value for @var{key} that is suitable for +lookups in a hashtable of size @var{size}, where @code{eq?} is +used as the equality predicate. The function returns an +integer in the range 0 to @var{size} - 1. Note that +@code{hashq} may use internal addresses. Thus two calls to +hashq where the keys are @code{eq?} are not guaranteed to +deliver the same value if the key object gets garbage collected +in between. This can happen, for example with symbols: +@code{(hashq 'foo n) (gc) (hashq 'foo n)} may produce two +different values, since @code{foo} will be garbage collected. +@end deffn + +@deffn primitive hashv key size +Determine a hash value for @var{key} that is suitable for +lookups in a hashtable of size @var{size}, where @code{eqv?} is +used as the equality predicate. The function returns an +integer in the range 0 to @var{size} - 1. Note that +@code{(hashv key)} may use internal addresses. Thus two calls +to hashv where the keys are @code{eqv?} are not guaranteed to +deliver the same value if the key object gets garbage collected +in between. This can happen, for example with symbols: +@code{(hashv 'foo n) (gc) (hashv 'foo n)} may produce two +different values, since @code{foo} will be garbage collected. +@end deffn + +@deffn primitive hash key size +Determine a hash value for @var{key} that is suitable for +lookups in a hashtable of size @var{size}, where @code{equal?} +is used as the equality predicate. The function returns an +integer in the range 0 to @var{size} - 1. +@end deffn + +@deffn primitive hashx-ref hash assoc table key [dflt] +This behaves the same way as the corresponding @code{ref} +function, but uses @var{hash} as a hash function and +@var{assoc} to compare keys. @code{hash} must be a function +that takes two arguments, a key to be hashed and a table size. +@code{assoc} must be an associator function, like @code{assoc}, +@code{assq} or @code{assv}. + +By way of illustration, @code{hashq-ref table key} is +equivalent to @code{hashx-ref hashq assq table key}. +@end deffn + +@deffn primitive hashx-set! hash assoc table key val +This behaves the same way as the corresponding @code{set!} +function, but uses @var{hash} as a hash function and +@var{assoc} to compare keys. @code{hash} must be a function +that takes two arguments, a key to be hashed and a table size. +@code{assoc} must be an associator function, like @code{assoc}, +@code{assq} or @code{assv}. + + By way of illustration, @code{hashq-set! table key} is +equivalent to @code{hashx-set! hashq assq table key}. +@end deffn + +@deffn primitive hashq-get-handle table key +This procedure returns the @code{(key . value)} pair from the +hash table @var{table}. If @var{table} does not hold an +associated value for @var{key}, @code{#f} is returned. +Uses @code{eq?} for equality testing. +@end deffn + +@deffn primitive hashv-get-handle table key +This procedure returns the @code{(key . value)} pair from the +hash table @var{table}. If @var{table} does not hold an +associated value for @var{key}, @code{#f} is returned. +Uses @code{eqv?} for equality testing. +@end deffn + +@deffn primitive hash-get-handle table key +This procedure returns the @code{(key . value)} pair from the +hash table @var{table}. If @var{table} does not hold an +associated value for @var{key}, @code{#f} is returned. +Uses @code{equal?} for equality testing. +@end deffn + +@deffn primitive hashx-get-handle hash assoc table key +This behaves the same way as the corresponding +@code{-get-handle} function, but uses @var{hash} as a hash +function and @var{assoc} to compare keys. @code{hash} must be +a function that takes two arguments, a key to be hashed and a +table size. @code{assoc} must be an associator function, like +@code{assoc}, @code{assq} or @code{assv}. +@end deffn + +@deffn primitive hashq-create-handle! table key init +This function looks up @var{key} in @var{table} and returns its handle. +If @var{key} is not already present, a new handle is created which +associates @var{key} with @var{init}. +@end deffn + +@deffn primitive hashv-create-handle! table key init +This function looks up @var{key} in @var{table} and returns its handle. +If @var{key} is not already present, a new handle is created which +associates @var{key} with @var{init}. +@end deffn + +@deffn primitive hash-create-handle! table key init +This function looks up @var{key} in @var{table} and returns its handle. +If @var{key} is not already present, a new handle is created which +associates @var{key} with @var{init}. +@end deffn + +@deffn primitive hashx-create-handle! hash assoc table key init +This behaves the same way as the corresponding +@code{-create-handle} function, but uses @var{hash} as a hash +function and @var{assoc} to compare keys. @code{hash} must be +a function that takes two arguments, a key to be hashed and a +table size. @code{assoc} must be an associator function, like +@code{assoc}, @code{assq} or @code{assv}. +@end deffn + +@deffn primitive hash-fold proc init table +An iterator over hash-table elements. +Accumulates and returns a result by applying PROC successively. +The arguments to PROC are "(key value prior-result)" where key +and value are successive pairs from the hash table TABLE, and +prior-result is either INIT (for the first application of PROC) +or the return value of the previous application of PROC. +For example, @code{(hash-fold acons '() tab)} will convert a hash +table into an a-list of key-value pairs. +@end deffn + + +@node Hooks +@section Hooks +@tpindex Hooks + +@c FIXME::martin: Review me! + +A hook is basically a list of procedures to be called at well defined +points in time. Hooks are used internally for several debugging +facilities, but they can be used in user code, too. + +Hooks are created with @code{make-hook}, then procedures can be added to +a hook with @code{add-hook!} or removed with @code{remove-hook!} or +@code{reset-hook!}. The procedures stored in a hook can be invoked with +@code{run-hook}. + +@menu +* Hook Examples:: Hook usage by example. +* Hook Reference:: Reference of all hook procedures. +@end menu + +@node Hook Examples +@subsection Hook Examples + +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. When the procedures have been added, we can invoke them +using @code{run-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))) +(run-hook hook 3 4) +@print{} Bar: 12 +@print{} Foo: 7 +@end lisp + +Note that the procedures are called in reverse order than they were +added. This can be changed by providing the optional third 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 +@subsection Hook Reference + +When a hook is created with @code{make-hook}, you can supply the arity +of the procedures which can be added to the hook. The arity defaults to +zero. All procedures of a hook must have the same arity, and when the +procedures are invoked using @code{run-hook}, the number of arguments +must match the arity of the procedures. + +The order in which procedures are added to a hook matters. If the third +parameter to @var{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 first to last when they are invoked via +@code{run-hook}. + +When calling @code{hook->list}, the procedures in the resulting list are +in the same order as they would have been called by @code{run-hook}. + +@deffn primitive 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 primitive hook? x +Return @code{#t} if @var{x} is a hook, @code{#f} otherwise. +@end deffn + +@deffn primitive hook-empty? hook +Return @code{#t} if @var{hook} is an empty hook, @code{#f} +otherwise. +@end deffn + +@deffn primitive add-hook! 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 primitive remove-hook! hook proc +Remove the procedure @var{proc} from the hook @var{hook}. The +return value of this procedure is not specified. +@end deffn + +@deffn primitive reset-hook! hook +Remove all procedures from the hook @var{hook}. The return +value of this procedure is not specified. +@end deffn + +@deffn primitive 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 + +@deffn primitive hook->list hook +Convert the procedure list of @var{hook} to a list. +@end deffn + + +@node Other Data Types +@section Other Core Guile Data Types + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-debug.texi b/doc/ref/scheme-debug.texi new file mode 100644 index 000000000..d9387f5d0 --- /dev/null +++ b/doc/ref/scheme-debug.texi @@ -0,0 +1,187 @@ +@page +@node Debugging +@chapter Internal Debugging Interface + +--- The name of this chapter needs to clearly distinguish it + from the appendix describing the debugger UI. The intro + should have a pointer to the UI appendix. + +@deffn primitive 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 occured 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 + +@deffn primitive 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 + +@deffn primitive 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 + +@deffn primitive backtrace +Display a backtrace of the stack saved by the last error +to the current output port. +@end deffn + +@deffn primitive malloc-stats +Return an alist ((@var{what} . @var{n}) ...) describing number +of malloced objects. +@var{what} is the second argument to @code{scm_must_malloc}, +@var{n} is the number of objects of that type currently +allocated. +@end deffn + +@deffn primitive debug-options-interface [setting] +Option interface for the debug options. Instead of using +this procedure directly, use the procedures @code{debug-enable}, +@code{debug-disable}, @code{debug-set!} and @var{debug-options}. +@end deffn + +@deffn primitive with-traps thunk +Call @var{thunk} with traps enabled. +@end deffn + +@deffn primitive memoized? obj +Return @code{#t} if @var{obj} is memoized. +@end deffn + +@deffn primitive unmemoize m +Unmemoize the memoized expression @var{m}, +@end deffn + +@deffn primitive memoized-environment m +Return the environment of the memoized expression @var{m}. +@end deffn + +@deffn primitive procedure-name proc +Return the name of the procedure @var{proc} +@end deffn + +@deffn primitive procedure-source proc +Return the source of the procedure @var{proc}. +@end deffn + +@deffn primitive procedure-environment proc +Return the environment of the procedure @var{proc}. +@end deffn + +@deffn primitive debug-object? obj +Return @code{#t} if @var{obj} is a debug object. +@end deffn + +@deffn primitive frame-arguments frame +Return the arguments of @var{frame}. +@end deffn + +@deffn primitive frame-evaluating-args? frame +Return @code{#t} if @var{frame} contains evaluated arguments. +@end deffn + +@deffn primitive 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 primitive frame-number frame +Return the frame number of @var{frame}. +@end deffn + +@deffn primitive frame-overflow? frame +Return @code{#t} if @var{frame} is an overflow frame. +@end deffn + +@deffn primitive 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 primitive frame-procedure frame +Return the procedure for @var{frame}, or @code{#f} if no +procedure is associated with @var{frame}. +@end deffn + +@deffn primitive frame-procedure? frame +Return @code{#t} if a procedure is associated with @var{frame}. +@end deffn + +@deffn primitive frame-real? frame +Return @code{#t} if @var{frame} is a real frame. +@end deffn + +@deffn primitive frame-source frame +Return the source of @var{frame}. +@end deffn + +@deffn primitive frame? obj +Return @code{#t} if @var{obj} is a stack frame. +@end deffn + +@deffn primitive 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 + +@deffn primitive 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 primitive stack-id stack +Return the identifier given to @var{stack} by @code{start-stack}. +@end deffn + +@deffn primitive stack-length stack +Return the length of @var{stack}. +@end deffn + +@deffn primitive stack-ref stack i +Return the @var{i}'th frame from @var{stack}. +@end deffn + +@deffn primitive stack? obj +Return @code{#t} if @var{obj} is a calling stack. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-evaluation.texi b/doc/ref/scheme-evaluation.texi new file mode 100644 index 000000000..210f26040 --- /dev/null +++ b/doc/ref/scheme-evaluation.texi @@ -0,0 +1,419 @@ +@page +@node Read/Load/Eval +@chapter 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 +@section Scheme Syntax: Standard and Guile Extensions + +@menu +* Expression Syntax:: +* Comments:: +* Block Comments:: +* Case Sensitivity:: +* Keyword Syntax:: +* Reader Extensions:: +@end menu + + +@node Expression Syntax +@subsection Expression Syntax + + +@node Comments +@subsection 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 +@subsection 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 +@subsection 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 +@subsection Keyword Syntax + + +@node Reader Extensions +@subsection Reader Extensions + +@deffn primitive 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 +@section Reading Scheme Code + +@rnindex read +@deffn primitive 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{General +option interface}. 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 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 procedure read-enable option-name +@deffnx procedure read-disable option-name +@deffnx 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 primitive read-options-interface [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 +@section Procedures for On the Fly Evaluation + +@rnindex eval +@c ARGFIXME environment/environment specifier +@deffn primitive eval exp environment +Evaluate @var{exp}, a list representing a Scheme expression, in the +environment given by @var{environment specifier}. +@end deffn + +@rnindex interaction-environment +@deffn primitive 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 primitive eval-string string +Evaluate @var{string} as the text representation of a Scheme +form or forms, and return whatever value they produce. +Evaluation takes place in the environment returned by the +procedure @code{interaction-environment}. +@end deffn + +@deffn primitive apply:nconc2last lst +Given a list (@var{arg1} @dots{} @var{args}), this function +conses the @var{arg1} @dots{} arguments onto the front of +@var{args}, and returns the resulting list. Note that +@var{args} is a list; thus, the argument to this function is +a list whose last element is a list. +Note: Rather than do new consing, @code{apply:nconc2last} +destroys its argument, so use with care. +@end deffn + +@rnindex apply +@deffn primitive apply proc arg1 @dots{} args +@var{proc} must be a procedure and @var{args} must be a list. Call +@var{proc} with the elements of the list @code{(append (list @var{arg1} +@dots{}) @var{args})} as the actual arguments. +@end deffn + +@deffn primitive primitive-eval exp +Evaluate @var{exp} in the top-level environment specified by +the current module. +@end deffn + +@deffn primitive eval2 obj env_thunk +Evaluate @var{exp}, a Scheme expression, in the environment +designated by @var{lookup}, a symbol-lookup function. +Do not use this version of eval, it does not play well +with the module system. Use @code{eval} or +@code{primitive-eval} instead. +@end deffn + +@deffn primitive read-and-eval! [port] +Read a form from @var{port} (standard input by default), and evaluate it +(memoizing it in the process) in the top-level environment. If no data +is left to be read from @var{port}, an @code{end-of-file} error is +signalled. +@end deffn + + +@node Loading +@section Loading Scheme Code from File + +@rnindex load +@deffn 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 procedure load-from-path filename +Similar to @code{load}, but searches for @var{filename} in the load +paths. +@end deffn + +@deffn primitive 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 primitive 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 primitive %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 primitive 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 +@section Delayed Evaluation + +[delay] + +@deffn primitive promise? obj +Return true if @var{obj} is a promise, i.e. a delayed computation +(@pxref{Delayed evaluation,,,r5rs.info,The Revised^5 Report on Scheme}). +@end deffn + +@rnindex force +@deffn primitive force x +If the promise @var{x} has not been computed yet, compute and +return @var{x}, otherwise just return the previously computed +value. +@end deffn + + +@node Local Evaluation +@section Local Evaluation + +[the-environment] + +@deffn primitive 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 +@section 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{General +option interface}. 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 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 procedure eval-enable option-name +@deffnx procedure eval-disable option-name +@deffnx 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 primitive 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 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 procedure trap-enable option-name +@deffnx procedure trap-disable option-name +@deffnx 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 primitive evaluator-traps-interface [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/scheme-ideas.texi b/doc/ref/scheme-ideas.texi new file mode 100644 index 000000000..80f5fbab4 --- /dev/null +++ b/doc/ref/scheme-ideas.texi @@ -0,0 +1,1458 @@ +@page +@node Basic Ideas +@chapter Basic Ideas in Scheme + +In this chapter, we introduce the basic concepts that underpin the +elegance and power of the Scheme language. + +Readers who already possess a background knowledge of Scheme may happily +skip this chapter. For the reader who is new to the language, however, +the following discussions on data, procedures, expressions and closure +are designed to provide a minimum level of Scheme understanding that is +more or less assumed by the reference chapters that follow. + +The style of this introductory material aims about halfway between the +terse precision of R5RS and the discursive randomness of a Scheme +tutorial. + +@menu +* About Data:: Latent typing, types, values and variables. +* About Procedures:: The representation and use of procedures. +* About Expressions:: All kinds of expressions and their meaning. +* About Closure:: Closure, scoping and environments. +@end menu + + +@node About Data +@section Data Types, Values and Variables + +This section discusses the representation of data types and values, what +it means for Scheme to be a @dfn{latently typed} language, and the role +of variables. We conclude by introducing the Scheme syntaxes for +defining a new variable, and for changing the value of an existing +variable. + +@menu +* Latent Typing:: Scheme as a "latently typed" language. +* Values and Variables:: About data types, values and variables. +* Definition:: Defining variables and setting their values. +@end menu + + +@node Latent Typing +@subsection Latent Typing + +The term @dfn{latent typing} is used to descibe a computer language, +such as Scheme, for which you cannot, @emph{in general}, simply look at +a program's source code and determine what type of data will be +associated with a particular variable, or with the result of a +particular expression. + +Sometimes, of course, you @emph{can} tell from the code what the type of +an expression will be. If you have a line in your program that sets the +variable @code{x} to the numeric value 1, you can be certain that, +immediately after that line has executed (and in the absence of multiple +threads), @code{x} has the numeric value 1. Or if you write a procedure +that is designed to concatenate two strings, it is likely that the rest +of your application will always invoke this procedure with two string +parameters, and quite probable that the procedure would go wrong in some +way if it was ever invoked with parameters that were not both strings. + +Nevertheless, the point is that there is nothing in Scheme which +requires the procedure parameters always to be strings, or @code{x} +always to hold a numeric value, and there is no way of declaring in your +program that such constraints should always be obeyed. In the same +vein, there is no way to declare the expected type of a procedure's +return value. + +Instead, the types of variables and expressions are only known -- in +general -- at run time. If you @emph{need} to check at some point that +a value has the expected type, Scheme provides run time procedures that +you can invoke to do so. But equally, it can be perfectly valid for two +separate invocations of the same procedure to specify arguments with +different types, and to return values with different types. + +The next subsection explains what this means in practice, for the ways +that Scheme programs use data types, values and variables. + + +@node Values and Variables +@subsection Values and Variables + +Scheme provides many data types that you can use to represent your data. +Primitive types include characters, strings, numbers and procedures. +Compound types, which allow a group of primitive and compound values to +be stored together, include lists, pairs, vectors and multi-dimensional +arrays. In addition, Guile allows applications to define their own data +types, with the same status as the built-in standard Scheme types. + +As a Scheme program runs, values of all types pop in and out of +existence. Sometimes values are stored in variables, but more commonly +they pass seamlessly from being the result of one computation to being +one of the parameters for the next. + +Consider an example. A string value is created because the interpreter +reads in a literal string from your program's source code. Then a +numeric value is created as the result of calculating the length of the +string. A second numeric value is created by doubling the calculated +length. Finally the program creates a list with two elements -- the +doubled length and the original string itself -- and stores this list in +a program variable. + +All of the values involved here -- in fact, all values in Scheme -- +carry their type with them. In other words, every value ``knows,'' at +runtime, what kind of value it is. A number, a string, a list, +whatever. + +A variable, on the other hand, has no fixed type. A variable -- +@code{x}, say -- is simply the name of a location -- a box -- in which +you can store any kind of Scheme value. So the same variable in a +program may hold a number at one moment, a list of procedures the next, +and later a pair of strings. The ``type'' of a variable -- insofar as +the idea is meaningful at all -- is simply the type of whatever value +the variable happens to be storing at a particular moment. + + +@node Definition +@subsection Defining and Setting Variables + +To define a new variable, you use Scheme's @code{define} syntax like +this: + +@lisp +(define @var{variable-name} @var{value}) +@end lisp + +This makes a new variable called @var{variable-name} and stores +@var{value} in it as the variable's initial value. For example: + +@lisp +;; Make a variable `x' with initial numeric value 1. +(define x 1) + +;; Make a variable `organization' with an initial string value. +(define organization "Free Software Foundation") +@end lisp + +(In Scheme, a semicolon marks the beginning of a comment that continues +until the end of the line. So the lines beginning @code{;;} are +comments.) + +Changing the value of an already existing variable is very similar, +except that @code{define} is replaced by the Scheme syntax @code{set!}, +like this: + +@lisp +(set! @var{variable-name} @var{new-value}) +@end lisp + +Remember that variables do not have fixed types, so @var{new-value} may +have a completely different type from whatever was previously stored in +the location named by @var{variable-name}. Both of the following +examples are therefore correct. + +@lisp +;; Change the value of `x' to 5. +(set! x 5) + +;; Change the value of `organization' to the FSF's street number. +(set! organization 545) +@end lisp + +In these examples, @var{value} and @var{new-value} are literal numeric +or string values. In general, however, @var{value} and @var{new-value} +can be any Scheme expression. Even though we have not yet covered the +forms that Scheme expressions can take (@pxref{About Expressions}), you +can probably guess what the following @code{set!} example does@dots{} + +@lisp +(set! x (+ x 1)) +@end lisp + +(Note: this is not a complete description of @code{define} and +@code{set!}, because we need to introduce some other aspects of Scheme +before the missing pieces can be filled in. If, however, you are +already familiar with the structure of Scheme, you may like to read +about those missing pieces immediately by jumping ahead to the following +references. + +@itemize @bullet +@item +@xref{Internal Definitions}, to read about using @code{define} other +than at top level in a Scheme program, including a discussion of when it +works to use @code{define} rather than @code{set!} to change the value +of an existing variable. + +@item +@ref{Lambda Alternatives}, to read about an alternative form of the +@code{define} syntax that can be used when defining new procedures. + +@item +REFFIXME, to read about an alternative form of the @code{set!} syntax +that helps with changing a single value in the depths of a compound data +structure.) +@end itemize + + +@node About Procedures +@section The Representation and Use of Procedures + +This section introduces the basics of using and creating Scheme +procedures. It discusses the representation of procedures as just +another kind of Scheme value, and shows how procedure invocation +expressions are constructed. We then explain how @code{lambda} is used +to create new procedures, and conclude by presenting the various +shorthand forms of @code{define} that can be used instead of writing an +explicit @code{lambda} expression. + +@menu +* Procedures as Values:: Procedures are values like everything else. +* Simple Invocation:: How to write a simple procedure invocation. +* Creating a Procedure:: How to create your own procedures. +* Lambda Alternatives:: Other ways of writing procedure definitions. +@end menu + + +@node Procedures as Values +@subsection Procedures as Values + +One of the great simplifications of Scheme is that a procedure is just +another type of value, and that procedure values can be passed around +and stored in variables in exactly the same way as, for example, strings +and lists. When we talk about a built-in standard Scheme procedure such +as @code{open-input-file}, what we actually mean is that there is a +pre-defined top level variable called @code{open-input-file}, whose +value is a procedure that implements what R5RS says that +@code{open-input-file} should do. + +Note that this is quite different from many dialects of Lisp --- +including Emacs Lisp --- in which a program can use the same name with +two quite separate meanings: one meaning identifies a Lisp function, +while the other meaning identifies a Lisp variable, whose value need +have nothing to do with the function that is associated with the first +meaning. In these dialects, functions and variables are said to live in +different @dfn{namespaces}. + +In Scheme, on the other hand, all names belong to a single unified +namespace, and the variables that these names identify can hold any kind +of Scheme value, including procedure values. + +One consequence of the ``procedures as values'' idea is that, if you +don't happen to like the standard name for a Scheme procedure, you can +change it. + +For example, @code{call-with-current-continuation} is a very important +standard Scheme procedure, but it also has a very long name! So, many +programmers use the following definition to assign the same procedure +value to the more convenient name @code{call/cc}. + +@lisp +(define call/cc call-with-current-continuation) +@end lisp + +Let's understand exactly how this works. The definition creates a new +variable @code{call/cc}, and then sets its value to the value of the +variable @code{call-with-current-continuation}; the latter value is a +procedure that implements the behaviour that R5RS specifies under the +name ``call-with-current-continuation''. So @code{call/cc} ends up +holding this value as well. + +Now that @code{call/cc} holds the required procedure value, you could +choose to use @code{call-with-current-continuation} for a completely +different purpose, or just change its value so that you will get an +error if you accidentally use @code{call-with-current-continuation} as a +procedure in your program rather than @code{call/cc}. For example: + +@lisp +(set! call-with-current-continuation "Not a procedure any more!") +@end lisp + +Or you could just leave @code{call-with-current-continuation} as it was. +It's perfectly fine for more than one variable to hold the same +procedure value. + + +@node Simple Invocation +@subsection Simple Procedure Invocation + +A procedure invocation in Scheme is written like this: + +@lisp +(@var{procedure} [@var{arg1} [@var{arg2} @dots{}]]) +@end lisp + +In this expression, @var{procedure} can be any Scheme expression whose +value is a procedure. Most commonly, however, @var{procedure} is simply +the name of a variable whose value is a procedure. + +For example, @code{string-append} is a standard Scheme procedure whose +behaviour is to concatenate together all the arguments, which are +expected to be strings, that it is given. So the expression + +@lisp +(string-append "/home" "/" "andrew") +@end lisp + +@noindent +is a procedure invocation whose result is the string value +@code{"/home/andrew"}. + +Similarly, @code{string-length} is a standard Scheme procedure that +returns the length of a single string argument, so + +@lisp +(string-length "abc") +@end lisp + +@noindent +is a procedure invocation whose result is the numeric value 3. + +Each of the parameters in a procedure invocation can itself be any +Scheme expression. Since a procedure invocation is itself a type of +expression, we can put these two examples together to get + +@lisp +(string-length (string-append "/home" "/" "andrew")) +@end lisp + +@noindent +--- a procedure invocation whose result is the numeric value 12. + +(You may be wondering what happens if the two examples are combined the +other way round. If we do this, we can make a procedure invocation +expression that is @emph{syntactically} correct: + +@lisp +(string-append "/home" (string-length "abc")) +@end lisp + +@noindent +but when this expression is executed, it will cause an error, because +the result of @code{(string-length "abc")} is a numeric value, and +@code{string-append} is not designed to accept a numeric value as one of +its arguments.) + + +@node Creating a Procedure +@subsection Creating and Using a New Procedure + +Scheme has lots of standard procedures, and Guile provides all of these +via predefined top level variables. All of these standard procedures +are documented in the later chapters of this reference manual. + +Before very long, though, you will want to create new procedures that +encapsulate aspects of your own applications' functionality. To do +this, you can use the famous @code{lambda} syntax. + +For example, the value of the following Scheme expression + +@lisp +(lambda (name address) @var{expression} @dots{}) +@end lisp + +@noindent +is a newly created procedure that takes two arguments: +@code{name} and @code{address}. The behaviour of the +new procedure is determined by the sequence of @var{expression}s in the +@dfn{body} of the procedure definition. (Typically, these +@var{expression}s would use the arguments in some way, or else there +wouldn't be any point in giving them to the procedure.) When invoked, +the new procedure returns a value that is the value of the last +@var{expression} in the procedure body. + +To make things more concrete, let's suppose that the two arguments are +both strings, and that the purpose of this procedure is to form a +combined string that includes these arguments. Then the full lambda +expression might look like this: + +@lisp +(lambda (name address) + (string-append "Name=" name ":Address=" address)) +@end lisp + +We noted in the previous subsection that the @var{procedure} part of a +procedure invocation expression can be any Scheme expression whose value +is a procedure. But that's exactly what a lambda expression is! So we +can use a lambda expression directly in a procedure invocation, like +this: + +@lisp +((lambda (name address) + (string-append "Name=" name ":Address=" address)) + "FSF" + "Cambridge") +@end lisp + +@noindent +This is a valid procedure invocation expression, whose result is the +string @code{"Name=FSF:Address=Cambridge"}. + +It it more common, though, to store the procedure value in a variable --- + +@lisp +(define make-combined-string + (lambda (name address) + (string-append "Name=" name ":Address=" address))) +@end lisp + +@noindent +--- and then to use the variable name in the procedure invocation: + +@lisp +(make-combined-string "FSF" "Cambridge") +@end lisp + +@noindent +Which has exactly the same result. + +It's important to note that procedures created using @code{lambda} have +exactly the same status as the standard built in Scheme procedures, and +can be invoked, passed around, and stored in variables in exactly the +same ways. + + +@node Lambda Alternatives +@subsection Lambda Alternatives + +Since it is so common in Scheme programs to want to create a procedure +and then store it in a variable, there is an alternative form of the +@code{define} syntax that allows you to do just that. + +A @code{define} expression of the form + +@lisp +(define (@var{name} [@var{arg1} [@var{arg2} @dots{}]]) + @var{expression} @dots{}) +@end lisp + +@noindent +is exactly equivalent to the longer form + +@lisp +(define @var{name} + (lambda ([@var{arg1} [@var{arg2} @dots{}]]) + @var{expression} @dots{})) +@end lisp + +So, for example, the definition of @code{make-combined-string} in the +previous subsection could equally be written: + +@lisp +(define (make-combined-string name address) + (string-append "Name=" name ":Address=" address)) +@end lisp + +This kind of procedure definition creates a procedure that requires +exactly the expected number of arguments. There are two further forms +of the @code{lambda} expression, which create a procedure that can +accept a variable number of arguments: + +@lisp +(lambda (@var{arg1} @dots{} . @var{args}) @var{expression} @dots{}) + +(lambda @var{args} @var{expression} @dots{}) +@end lisp + +@noindent +The corresponding forms of the alternative @code{define} syntax are: + +@lisp +(define (@var{name} @var{arg1} @dots{} . @var{args}) @var{expression} @dots{}) + +(define (@var{name} . @var{args}) @var{expression} @dots{}) +@end lisp + +@noindent +For details on how these forms work, see @xref{Lambda}. + +(It could be argued that the alternative @code{define} forms are rather +confusing, especially for newcomers to the Scheme language, as they hide +both the role of @code{lambda} and the fact that procedures are values +that are stored in variables in the some way as any other kind of value. +On the other hand, they are very convenient, and they are also a good +example of another of Scheme's powerful features: the ability to specify +arbitrary syntactic transformations at run time, which can be applied to +subsequently read input.) + + +@node About Expressions +@section Expressions and Evaluation + +So far, we have met expressions that @emph{do} things, such as the +@code{define} expressions that create and initialize new variables, and +we have also talked about expressions that have @emph{values}, for +example the value of the procedure invocation expression: + +@lisp +(string-append "/home" "/" "andrew") +@end lisp + +@noindent +but we haven't yet been precise about what causes an expression like +this procedure invocation to be reduced to its ``value'', or how the +processing of such expressions relates to the execution of a Scheme +program as a whole. + +This section clarifies what we mean by an expression's value, by +introducing the idea of @dfn{evaluation}. It discusses the side effects +that evaluation can have, explains how each of the various types of +Scheme expression is evaluated, and describes the behaviour and use of +the Guile REPL as a mechanism for exploring evaluation. The section +concludes with a very brief summary of Scheme's common syntactic +expressions. + +@menu +* Evaluating:: How a Scheme program is executed. +* The REPL:: Interacting with the Guile interpreter. +* Syntax Summary:: Common syntactic expressions -- in brief. +@end menu + + +@node Evaluating +@subsection Evaluating Expressions and Executing Programs + +In Scheme, the process of executing an expression is known as +@dfn{evaluation}. Evaluation has two kinds of result: + +@itemize @bullet +@item +the @dfn{value} of the evaluated expression + +@item +the @dfn{side effects} of the evaluation, which consist of any effects of +evaluating the expression that are not represented by the value. +@end itemize + +Of the expressions that we have met so far, @code{define} and +@code{set!} expressions have side effects --- the creation or +modification of a variable --- but no value; @code{lambda} expressions +have values --- the newly constructed procedures --- but no side +effects; and procedure invocation expressions, in general, have either +values, or side effects, or both. + +It is tempting to try to define more intuitively what we mean by +``value'' and ``side effects'', and what the difference between them is. +In general, though, this is extremely difficult. It is also +unnecessary; instead, we can quite happily define the behaviour of a +Scheme program by specifying how Scheme executes a program as a whole, +and then by describing the value and side effects of evaluation for each +type of expression individually. + +@noindent +So, some@footnote{These definitions are approximate. For the whole and +detailed truth, see @xref{Formal syntax and semantics,R5RS +syntax,,r5rs}.} definitions@dots{} + +@itemize @bullet + +@item +A Scheme program consists of a sequence of expressions. + +@item +A Scheme interpreter executes the program by evaluating these +expressions in order, one by one. + +@item +An expression can be + +@itemize @bullet +@item +a piece of literal data, such as a number @code{2.3} or a string +@code{"Hello world!"} +@item +a variable name +@item +a procedure invocation expression +@item +one of Scheme's special syntactic expressions. +@end itemize +@end itemize + +@noindent +The following subsections describe how each of these types of expression +is evaluated. + +@menu +* Eval Literal:: Evaluating literal data. +* Eval Variable:: Evaluating variable references. +* Eval Procedure:: Evaluating procedure invocation expressions. +* Eval Special:: Evaluating special syntactic expressions. +@end menu + +@node Eval Literal +@subsubsection Evaluating Literal Data + +When a literal data expression is evaluated, the value of the expression +is simply the value that the expression describes. The evaluation of a +literal data expression has no side effects. + +@noindent +So, for example, + +@itemize @bullet +@item +the value of the expression @code{"abc"} is the string value +@code{"abc"} + +@item +the value of the expression @code{3+4i} is the complex number 3 + 4i + +@item +the value of the expression @code{#(1 2 3)} is a three-element vector +containing the numeric values 1, 2 and 3. +@end itemize + +For any data type which can be expressed literally like this, the syntax +of the literal data expression for that data type --- in other words, +what you need to write in your code to indicate a literal value of that +type --- is known as the data type's @dfn{read syntax}. This manual +specifies the read syntax for each such data type in the section that +describes that data type. + +Some data types do not have a read syntax. Procedures, for example, +cannot be expressed as literal data; they must be created using a +@code{lambda} expression (@pxref{Creating a Procedure}) or implicitly +using the shorthand form of @code{define} (@pxref{Lambda Alternatives}). + + +@node Eval Variable +@subsubsection Evaluating a Variable Reference + +When an expression that consists simply of a variable name is evaluated, +the value of the expression is the value of the named variable. The +evaluation of a variable reference expression has no side effects. + +So, after + +@lisp +(define key "Paul Evans") +@end lisp + +@noindent +the value of the expression @code{key} is the string value @code{"Paul +Evans"}. If @var{key} is then modified by + +@lisp +(set! key 3.74) +@end lisp + +@noindent +the value of the expression @code{key} is the numeric value 3.74. + +If there is no variable with the specified name, evaluation of the +variable reference expression signals an error. + + +@node Eval Procedure +@subsubsection Evaluating a Procedure Invocation Expression + +This is where evaluation starts getting interesting! As already noted, +a procedure invocation expression has the form + +@lisp +(@var{procedure} [@var{arg1} [@var{arg2} @dots{}]]) +@end lisp + +@noindent +where @var{procedure} must be an expression whose value, when evaluated, +is a procedure. + +The evaluation of a procedure invocation expression like this proceeds +by + +@itemize @bullet +@item +evaluating individually the expressions @var{procedure}, @var{arg1}, +@var{arg2}, and so on + +@item +calling the procedure that is the value of the @var{procedure} +expression with the list of values obtained from the evaluations of +@var{arg1}, @var{arg2} etc. as its parameters. +@end itemize + +For a procedure defined in Scheme, ``calling the procedure with the list +of values as its parameters'' means binding the values to the +procedure's formal parameters and then evaluating the sequence of +expressions that make up the body of the procedure definition. The +value of the procedure invocation expression is the value of the last +evaluated expression in the procedure body. The side effects of calling +the procedure are the combination of the side effects of the sequence of +evaluations of expressions in the procedure body. + +For a built-in procedure, the value and side-effects of calling the +procedure are best described by that procedure's documentation. + +Note that the complete side effects of evaluating a procedure invocation +expression consist not only of the side effects of the procedure call, +but also of any side effects of the preceding evaluation of the +expressions @var{procedure}, @var{arg1}, @var{arg2}, and so on. + +To illustrate this, let's look again at the procedure invocation +expression: + +@lisp +(string-length (string-append "/home" "/" "andrew")) +@end lisp + +In the outermost expression, @var{procedure} is @code{string-length} and +@var{arg1} is @code{(string-append "/home" "/" "andrew")}. + +@itemize @bullet +@item +Evaluation of @code{string-length}, which is a variable, gives a +procedure value that implements the expected behaviour for +``string-length''. + +@item +Evaluation of @code{(string-append "/home" "/" "andrew")}, which is +another procedure invocation expression, means evaluating each of + +@itemize @bullet +@item +@code{string-append}, which gives a procedure value that implements the +expected behaviour for ``string-append'' + +@item +@code{"/home"}, which gives the string value @code{"/home"} + +@item +@code{"/"}, which gives the string value @code{"/"} + +@item +@code{"andrew"}, which gives the string value @code{"andrew"} +@end itemize + +and then invoking the procedure value with this list of string values as +its arguments. The resulting value is a single string value that is the +concatenation of all the arguments, namely @code{"/home/andrew"}. +@end itemize + +In the evaluation of the outermost expression, the interpreter can now +invoke the procedure value obtained from @var{procedure} with the value +obtained from @var{arg1} as its arguments. The resulting value is a +numeric value that is the length of the argument string, which is 12. + + +@node Eval Special +@subsubsection Evaluating Special Syntactic Expressions + +When a procedure invocation expression is evaluated, the procedure and +@emph{all} the argument expressions must be evaluated before the +procedure can be invoked. Special syntactic expressions are special +because they are able to manipulate their arguments in an unevaluated +form, and can choose whether to evaluate any or all of the argument +expressions. + +Why is this needed? Consider a program fragment that asks the user +whether or not to delete a file, and then deletes the file if the user +answers yes. + +@lisp +(if (string=? (read-answer "Should I delete this file?") + "yes") + (delete-file file)) +@end lisp + +If the outermost @code{(if @dots{})} expression here was a procedure +invocation expression, the expression @code{(delete-file file)}, whose +effect is to actually delete a file, would already have been executed +before the @code{if} procedure even got invoked! Clearly this is no use +--- the whole point of an @code{if} expression is that the +@dfn{consequent} expression is only evaluated if the condition of the +@code{if} expression is ``true''. + +Therefore @code{if} must be special syntax, not a procedure. Other +special syntaxes that we have already met are @code{define}, @code{set!} +and @code{lambda}. @code{define} and @code{set!} are syntax because +they need to know the variable @emph{name} that is given as the first +argument in a @code{define} or @code{set!} expression, not that +variable's value. @code{lambda} is syntax because it does not +immediately evaluate the expressions that define the procedure body; +instead it creates a procedure object that incorporates these +expressions so that they can be evaluated in the future, when that +procedure is invoked. + +The rules for evaluating each special syntactic expression are specified +individually for each special syntax. For a summary of standard special +syntax, see @xref{Syntax Summary}. + + +@node The REPL +@subsection Using the Guile REPL + +If you start Guile without specifying a particular program for it to +execute, Guile enters its standard Read Evaluate Print Loop --- or +@dfn{REPL} for short. In this mode, Guile repeatedly reads in the next +Scheme expression that the user types, evaluates it, and prints the +resulting value. + +The REPL is a useful mechanism for exploring the evaluation behaviour +described in the previous subsection. If you type @code{string-append}, +for example, the REPL replies @code{#<primitive-procedure +string-append>}, illustrating the relationship between the variable +@code{string-append} and the procedure value stored in that variable. + +In this manual, the notation @result{} is used to mean ``evaluates +to''. Wherever you see an example of the form + +@lisp +@var{expression} +@result{} +@var{result} +@end lisp + +@noindent +feel free to try it out yourself by typing @var{expression} into the +REPL and checking that it gives the expected @var{result}. + + +@node Syntax Summary +@subsection Summary of Common Syntax + +This subsection lists the most commonly used Scheme syntactic +expressions, simply so that you will recognize common special syntax +when you see it. For a full description of each of these syntaxes, +follow the appropriate reference. + +@code{if} and @code{cond} (@pxref{if cond case}) provide conditional +evaluation of argument expressions depending on whether one or more +conditions evaluate to ``true'' or ``false''. + +@code{case} (@pxref{if cond case}) provides conditional evaluation of +argument expressions depending on whether a variable has one of a +specified group of values. + +@code{define} (REFFIXME) is used to create a new variable and set its +initial value. + +@code{set!} (REFFIXME) is used to modify an existing variable's value. + +@code{lambda} (@pxref{Lambda}) is used to construct procedure objects. + +@code{let}, @code{let*} and @code{letrec} (@pxref{Local Bindings}) +create an inner lexical environment for the evaluation of a sequence of +expressions, in which a specified set of local variables is bound to the +values of a corresponding set of expressions. For an introduction to +environments, see @xref{About Closure}. + +@code{begin} (@pxref{begin}) executes a sequence of expressions in order +and returns the value of the last expression. Note that this is not the +same as a procedure which returns its last argument, because the +evaluation of a procedure invocation expression does not guarantee to +evaluate the arguments in order. + +@code{and} (@pxref{and or}) executes a sequence of expressions in order +until either there are no expressions left, or one of them evaluates to +``false''. + +@code{or} (@pxref{and or}) executes a sequence of expressions in order +until either there are no expressions left, or one of them evaluates to +``true''. + + +@node About Closure +@section The Concept of Closure + +@cindex closure + +The concept of @dfn{closure} is the idea that a lambda expression +``captures'' the variable bindings that are in lexical scope at the +point where the lambda expression occurs. The procedure created by the +lambda expression can refer to and mutate the captured bindings, and the +values of those bindings persist between procedure calls. + +This section explains and explores the various parts of this idea in +more detail. + +@menu +* About Environments:: Names, locations, values and environments. +* Local Variables:: Local variables and local environments. +* Chaining:: Environment chaining. +* Lexical Scope:: The meaning of lexical scoping. +* Closure:: Explaining the concept of closure. +* Serial Number:: Example 1: a serial number generator. +* Shared Variable:: Example 2: a shared persistent variable. +* Callback Closure:: Example 3: the callback closure problem. +* OO Closure:: Example 4: object orientation. +@end menu + +@node About Environments +@subsection Names, Locations, Values and Environments + +@cindex location +@cindex environment +@cindex vcell +@cindex top level environment +@cindex environment, top level + +We said earlier that a variable name in a Scheme program is associated +with a location in which any kind of Scheme value may be stored. +(Incidentally, the term ``vcell'' is often used in Lisp and Scheme +circles as an alternative to ``location''.) Thus part of what we mean +when we talk about ``creating a variable'' is in fact establishing an +association between a name, or identifier, that is used by the Scheme +program code, and the variable location to which that name refers. +Although the value that is stored in that location may change, the +location to which a given name refers is always the same. + +We can illustrate this by breaking down the operation of the +@code{define} syntax into three parts: @code{define} + +@itemize @bullet +@item +creates a new location + +@item +establishes an association between that location and the name specified +as the first argument of the @code{define} expression + +@item +stores in that location the value obtained by evaluating the second +argument of the @code{define} expression. +@end itemize + +A collection of associations between names and locations is called an +@dfn{environment}. When you create a top level variable in a program +using @code{define}, the name-location association for that variable is +added to the ``top level'' environment. The ``top level'' environment +also includes name-location associations for all the procedures that are +supplied by standard Scheme. + +It is also possible to create environments other than the top level one, +and to create variable bindings, or name-location associations, in those +environments. This ability is a key ingredient in the concept of +closure; the next subsection shows how it is done. + + +@node Local Variables +@subsection Local Variables and Environments + +@cindex local variable +@cindex variable, local +@cindex local environment +@cindex environment, local + +We have seen how to create top level variables using the @code{define} +syntax (@pxref{Definition}). It is often useful to create variables +that are more limited in their scope, typically as part of a procedure +body. In Scheme, this is done using the @code{let} syntax, or one of +its modified forms @code{let*} and @code{letrec}. These syntaxes are +described in full later in the manual (@pxref{Local Bindings}). Here +our purpose is to illustrate their use just enough that we can see how +local variables work. + +For example, the following code uses a local variable @code{s} to +simplify the computation of the area of a triangle given the lengths of +its three sides. + +@lisp +(define a 5.3) +(define b 4.7) +(define c 2.8) + +(define area + (let ((s (/ (+ a b c) 2))) + (sqrt (* s (- s a) (- s b) (- s c))))) +@end lisp + +The effect of the @code{let} expression is to create a new environment +and, within this environment, an association between the name @code{s} +and a new location whose initial value is obtained by evaluating +@code{(/ (+ a b c) 2)}. The expressions in the body of the @code{let}, +namely @code{(sqrt (* s (- s a) (- s b) (- s c)))}, are then evaluated +in the context of the new environment, and the value of the last +expression evaluated becomes the value of the whole @code{let} +expression, and therefore the value of the variable @code{area}. + + +@node Chaining +@subsection Environment Chaining + +@cindex shadowing an imported variable binding +@cindex chaining environments + +In the example of the previous subsection, we glossed over an important +point. The body of the @code{let} expression in that example refers not +only to the local variable @code{s}, but also to the top level variables +@code{a}, @code{b}, @code{c} and @code{sqrt}. (@code{sqrt} is the +standard Scheme procedure for calculating a square root.) If the body +of the @code{let} expression is evaluated in the context of the +@emph{local} @code{let} environment, how does the evaluation get at the +values of these top level variables? + +The answer is that the local environment created by a @code{let} +expression automatically has a reference to its containing environment +--- in this case the top level environment --- and that the Scheme +interpreter automatically looks for a variable binding in the containing +environment if it doesn't find one in the local environment. More +generally, every environment except for the top level one has a +reference to its containing environment, and the interpreter keeps +searching back up the chain of environments --- from most local to top +level --- until it either finds a variable binding for the required +identifier or exhausts the chain. + +This description also determines what happens when there is more than +one variable binding with the same name. Suppose, continuing the +example of the previous subsection, that there was also a pre-existing +top level variable @code{s} created by the expression: + +@lisp +(define s "Some beans, my lord!") +@end lisp + +Then both the top level environment and the local @code{let} environment +would contain bindings for the name @code{s}. When evaluating code +within the @code{let} body, the interpreter looks first in the local +@code{let} environment, and so finds the binding for @code{s} created by +the @code{let} syntax. Even though this environment has a reference to +the top level environment, which also has a binding for @code{s}, the +interpreter doesn't get as far as looking there. When evaluating code +outside the @code{let} body, the interpreter looks up variable names in +the top level environment, so the name @code{s} refers to the top level +variable. + +Within the @code{let} body, the binding for @code{s} in the local +environment is said to @dfn{shadow} the binding for @code{s} in the top +level environment. + + +@node Lexical Scope +@subsection Lexical Scope + +The rules that we have just been describing are the details of how +Scheme implements ``lexical scoping''. This subsection takes a brief +diversion to explain what lexical scope means in general and to present +an example of non-lexical scoping. + +``Lexical scope'' in general is the idea that + +@itemize @bullet +@item +an identifier at a particular place in a program always refers to the +same variable location --- where ``always'' means ``every time that the +containing expression is executed'', and that + +@item +the variable location to which it refers can be determined by static +examination of the source code context in which that identifier appears, +without having to consider the flow of execution through the program as +a whole. +@end itemize + +In practice, lexical scoping is the norm for most programming languages, +and probably corresponds to what you would intuitively consider to be +``normal''. You may even be wondering how the situation could possibly +--- and usefully --- be otherwise. To demonstrate that another kind of +scoping is possible, therefore, and to compare it against lexical +scoping, the following subsection presents an example of non-lexical +scoping and examines in detail how its behavior differs from the +corresponding lexically scoped code. + +@menu +* Scoping Example:: An example of non-lexical scoping. +@end menu + + +@node Scoping Example +@subsubsection An Example of Non-Lexical Scoping + +To demonstrate that non-lexical scoping does exist and can be useful, we +present the following example from Emacs Lisp, which is a ``dynamically +scoped'' language. + +@lisp +(defvar currency-abbreviation "USD") + +(defun currency-string (units hundredths) + (concat currency-abbreviation + (number-to-string units) + "." + (number-to-string hundredths))) + +(defun french-currency-string (units hundredths) + (let ((currency-abbreviation "FRF")) + (currency-string units hundredths))) +@end lisp + +The question to focus on here is: what does the identifier +@code{currency-abbreviation} refer to in the @code{currency-string} +function? The answer, in Emacs Lisp, is that all variable bindings go +onto a single stack, and that @code{currency-abbreviation} refers to the +topmost binding from that stack which has the name +``currency-abbreviation''. The binding that is created by the +@code{defvar} form, to the value @code{"USD"}, is only relevant if none +of the code that calls @code{currency-string} rebinds the name +``currency-abbreviation'' in the meanwhile. + +The second function @code{french-currency-string} works precisely by +taking advantage of this behaviour. It creates a new binding for the +name ``currency-abbreviation'' which overrides the one established by +the @code{defvar} form. + +@lisp +;; Note! This is Emacs Lisp evaluation, not Scheme! +(french-currency-string 33 44) +@result{} +"FRF33.44" +@end lisp + +Now let's look at the corresponding, @emph{lexically scoped} Scheme +code: + +@lisp +(define currency-abbreviation "USD") + +(define (currency-string units hundredths) + (string-append currency-abbreviation + (number->string units) + "." + (number->string hundredths))) + +(define (french-currency-string units hundredths) + (let ((currency-abbreviation "FRF")) + (currency-string units hundredths))) +@end lisp + +According to the rules of lexical scoping, the +@code{currency-abbreviation} in @code{currency-string} refers to the +variable location in the innermost environment at that point in the code +which has a binding for @code{currency-abbreviation}, which is the +variable location in the top level environment created by the preceding +@code{(define currency-abbreviation @dots{})} expression. + +In Scheme, therefore, the @code{french-currency-string} procedure does +not work as intended. The variable binding that it creates for +``currency-abbreviation'' is purely local to the code that forms the +body of the @code{let} expression. Since this code doesn't directly use +the name ``currency-abbreviation'' at all, the binding is pointless. + +@lisp +(french-currency-string 33 44) +@result{} +"USD33.44" +@end lisp + +This begs the question of how the Emacs Lisp behaviour can be +implemented in Scheme. In general, this is a design question whose +answer depends upon the problem that is being addressed. In this case, +the best answer may be that @code{currency-string} should be +redesigned so that it can take an optional third argument. This third +argument, if supplied, is interpreted as a currency abbreviation that +overrides the default. + +It is possible to change @code{french-currency-string} so that it mostly +works without changing @code{currency-string}, but the fix is inelegant, +and susceptible to interrupts that could leave the +@code{currency-abbreviation} variable in the wrong state: + +@lisp +(define (french-currency-string units hundredths) + (set! currency-abbreviation "FRF") + (let ((result (currency-string units hundredths))) + (set! currency-abbreviation "USD") + result)) +@end lisp + +The key point here is that the code does not create any local binding +for the identifier @code{currency-abbreviation}, so all occurences of +this identifier refer to the top level variable. + + +@node Closure +@subsection Closure + +Consider a @code{let} expression that doesn't contain any +@code{lambda}s: + +@lisp +(let ((s (/ (+ a b c) 2))) + (sqrt (* s (- s a) (- s b) (- s c)))) +@end lisp + +@noindent +When the Scheme interpreter evaluates this, it + +@itemize @bullet +@item +creates a new environment with a reference to the environment that was +current when it encountered the @code{let} + +@item +creates a variable binding for @code{s} in the new environment, with +value given by @code{(/ (+ a b c) 2)} + +@item +evaluates the expression in the body of the @code{let} in the context of +the new local environment, and remembers the value @code{V} + +@item +forgets the local environment + +@item +continues evaluating the expression that contained the @code{let}, using +the value @code{V} as the value of the @code{let} expression, in the +context of the containing environment. +@end itemize + +After the @code{let} expression has been evaluated, the local +environment that was created is simply forgotten, and there is no longer +any way to access the binding that was created in this environment. If +the same code is evaluated again, it will follow the same steps again, +creating a second new local environment that has no connection with the +first, and then forgetting this one as well. + +If the @code{let} body contains a @code{lambda} expression, however, the +local environment is @emph{not} forgotten. Instead, it becomes +associated with the procedure that is created by the @code{lambda} +expression, and is reinstated every time that that procedure is called. +In detail, this works as follows. + +@itemize @bullet +@item +When the Scheme interpreter evaluates a @code{lambda} expression, to +create a procedure object, it stores the current environment as part of +the procedure definition. + +@item +Then, whenever that procedure is called, the interpreter reinstates the +environment that is stored in the procedure definition and evaluates the +procedure body within the context of that environment. +@end itemize + +The result is that the procedure body is always evaluated in the context +of the environment that was current when the procedure was created. + +This is what is meant by @dfn{closure}. The next few subsections +present examples that explore the usefulness of this concept. + + +@node Serial Number +@subsection Example 1: A Serial Number Generator + +This example uses closure to create a procedure with a variable binding +that is private to the procedure, like a local variable, but whose value +persists between procedure calls. + +@lisp +(define (make-serial-number-generator) + (let ((current-serial-number 0)) + (lambda () + (set! current-serial-number (+ current-serial-number 1)) + current-serial-number))) + +(define entry-sn-generator (make-serial-number-generator)) + +(entry-sn-generator) +@result{} +1 + +(entry-sn-generator) +@result{} +2 +@end lisp + +When @code{make-serial-number-generator} is called, it creates a local +environment with a binding for @code{current-serial-number} whose +initial value is 0, then, within this environment, creates a procedure. +The local environment is stored within the created procedure object and +so persists for the lifetime of the created procedure. + +Every time the created procedure is invoked, it increments the value of +the @code{current-serial-number} binding in the captured environment and +then returns the current value. + +Note that @code{make-serial-number-generator} can be called again to +create a second serial number generator that is independent of the +first. Every new invocation of @code{make-serial-number-generator} +creates a new local @code{let} environment and returns a new procedure +object with an association to this environment. + + +@node Shared Variable +@subsection Example 2: A Shared Persistent Variable + +This example uses closure to create two procedures, @code{get-balance} +and @code{deposit}, that both refer to the same captured local +environment so that they can both access the @code{balance} variable +binding inside that environment. The value of this variable binding +persists between calls to either procedure. + +Note that the captured @code{balance} variable binding is private to +these two procedures: it is not directly accessible to any other code. +It can only be accessed indirectly via @code{get-balance} or +@code{deposit}, as illustrated by the @code{withdraw} procedure. + +@lisp +(define get-balance #f) +(define deposit #f) + +(let ((balance 0)) + (set! get-balance + (lambda () + balance)) + (set! deposit + (lambda (amount) + (set! balance (+ balance amount)) + balance))) + +(define (withdraw amount) + (deposit (- amount))) + +(get-balance) +@result{} +0 + +(deposit 50) +@result{} +50 + +(withdraw 75) +@result{} +-25 +@end lisp + +A detail here is that the @code{get-balance} and @code{deposit} +variables must be set up by @code{define}ing them at top level and then +@code{set!}ing their values inside the @code{let} body. Using +@code{define} within the @code{let} body would not work: this would +create variable bindings within the local @code{let} environment that +would not be accessible at top level. + + +@node Callback Closure +@subsection Example 3: The Callback Closure Problem + +A frequently used programming model for library code is to allow an +application to register a callback function for the library to call when +some particular event occurs. It is often useful for the application to +make several such registrations using the same callback function, for +example if several similar library events can be handled using the same +application code, but the need then arises to distinguish the callback +function calls that are associated with one callback registration from +those that are associated with different callback registrations. + +In languages without the ability to create functions dynamically, this +problem is usually solved by passing a @code{user_data} parameter on the +registration call, and including the value of this parameter as one of +the parameters on the callback function. Here is an example of +declarations using this solution in C: + +@example +typedef void (event_handler_t) (int event_type, + void *user_data); + +void register_callback (int event_type, + event_handler_t *handler, + void *user_data); +@end example + +In Scheme, closure can be used to achieve the same functionality without +requiring the library code to store a @code{user-data} for each callback +registration. + +@lisp +;; In the library: + +(define (register-callback event-type handler-proc) + @dots{}) + +;; In the application: + +(define (make-handler event-type user-data) + (lambda () + @dots{} + <code referencing event-type and user-data> + @dots{})) + +(register-callback event-type + (make-handler event-type @dots{})) +@end lisp + +As far as the library is concerned, @code{handler-proc} is a procedure +with no arguments, and all the library has to do is call it when the +appropriate event occurs. From the application's point of view, though, +the handler procedure has used closure to capture an environment that +includes all the context that the handler code needs --- +@code{event-type} and @code{user-data} --- to handle the event +correctly. + + +@node OO Closure +@subsection Example 4: Object Orientation + +Closure is the capture of an environment, containing persistent variable +bindings, within the definition of a procedure or a set of related +procedures. This is rather similar to the idea in some object oriented +languages of encapsulating a set of related data variables inside an +``object'', together with a set of ``methods'' that operate on the +encapsulated data. The following example shows how closure can be used +to emulate the ideas of objects, methods and encapsulation in Scheme. + +@lisp +(define (make-account) + (let ((balance 0)) + (define (get-balance) + balance) + (define (deposit amount) + (set! balance (+ balance amount)) + balance) + (define (withdraw amount) + (deposit (- amount))) + + (lambda args + (apply + (case (car args) + ((get-balance) get-balance) + ((deposit) deposit) + ((withdraw) withdraw) + (else (error "Invalid method!"))) + (cdr args))))) +@end lisp + +Each call to @code{make-account} creates and returns a new procedure, +created by the expression in the example code that begins ``(lambda +args''. + +@lisp +(define my-account (make-account)) + +my-account +@result{} +#<procedure args> +@end lisp + +This procedure acts as an account object with methods +@code{get-balance}, @code{deposit} and @code{withdraw}. To apply one of +the methods to the account, you call the procedure with a symbol +indicating the required method as the first parameter, followed by any +other parameters that are required by that method. + +@lisp +(my-account 'get-balance) +@result{} +0 + +(my-account 'withdraw 5) +@result{} +-5 + +(my-account 'deposit 396) +@result{} +391 + +(my-account 'get-balance) +@result{} +391 +@end lisp + +Note how, in this example, both the current balance and the helper +procedures @code{get-balance}, @code{deposit} and @code{withdraw}, used +to implement the guts of the account object's methods, are all stored in +variable bindings within the private local environment captured by the +@code{lambda} expression that creates the account object procedure. + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-indices.texi b/doc/ref/scheme-indices.texi new file mode 100644 index 000000000..03a21bb30 --- /dev/null +++ b/doc/ref/scheme-indices.texi @@ -0,0 +1,17 @@ +@page +@node R5RS Index +@chapter R5RS Index + +@printindex rn + + +@page +@node Guile Extensions Index +@chapter Guile Extensions Index + +@printindex ge + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-intro.texi b/doc/ref/scheme-intro.texi new file mode 100644 index 000000000..5bac00086 --- /dev/null +++ b/doc/ref/scheme-intro.texi @@ -0,0 +1,55 @@ +@page +@node Scheme Intro +@chapter Introduction to Guile Scheme + +Guile's core language is Scheme, which is specified and described in the +series of reports known as @dfn{RnRS}. @dfn{RnRS} is shorthand for the +@iftex +@dfn{Revised$^n$ Report on the Algorithmic Language Scheme}. +@end iftex +@ifnottex +@dfn{Revised^n Report on the Algorithmic Language Scheme}. +@end ifnottex +The current latest revision of RnRS is version 5 +(@pxref{Top,R5RS,,r5rs}), and Guile 1.4 is fully compliant with the +Scheme specification in this revision. + +But Guile, like most Scheme implementations, also goes beyond R5RS in +many ways, because R5RS does not give specifications (or even +recommendations) regarding many issues that are important in practical +programming. Some of the areas where Guile extends R5RS are: + +@itemize @bullet +@item +Guile's interactive documentation system + +@item +Guile's support for POSIX-compliant network programming + +@item +GOOPS -- Guile's framework for object oriented programming. +@end itemize + +@menu +* Scheme Layout:: The layout of this part of the manual. +@end menu + + +@node Scheme Layout +@section Layout + +This part of the reference manual documents all of Guile's core +Scheme-level language and features in functionally-related groups. +Where a particular section of the manual includes both R5RS-compliant +parts and Guile-specific extensions, the text indicates which parts of +the documentation describe R5RS behaviour and which parts describe Guile +extensions. + +For a breakdown of Guile's core language and features in terms of what +is R5RS-compliant and what is Guile-specific, see the corresponding +indices: @ref{R5RS Index} and @ref{Guile Extensions Index}. + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-io.texi b/doc/ref/scheme-io.texi new file mode 100644 index 000000000..c775c165c --- /dev/null +++ b/doc/ref/scheme-io.texi @@ -0,0 +1,826 @@ +@page +@node Input and Output +@chapter 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. +@end menu + + +@node Ports +@section Ports + +[Concept of the port abstraction.] + +Sequential input/output in Scheme is represented by operations on a +@dfn{port}. Characters can be read from an input port and +written to an output port. This chapter explains the operations +that Guile provides for working with ports. + +The formal definition of a port is very generic: an input port is +simply ``an object which can deliver characters on command,'' 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. + +@rnindex input-port? +@deffn primitive input-port? 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 primitive output-port? 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 primitive port? 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 +@section Reading + +[Generic procedures for reading from ports.] + +@rnindex eof-object? +@deffn primitive eof-object? x +Return @code{#t} if @var{x} is an end-of-file object; otherwise +return @code{#f}. +@end deffn + +@rnindex char-ready? +@deffn primitive char-ready? [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 primitive 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 + +@rnindex peek-char? +@deffn primitive 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 primitive 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 primitive unread-string str port +Place the string @var{str} in @var{port} so that its characters will be +read in subsequent read operations. If called multiple times, the +unread characters will be read again in last-in first-out order. If +@var{port} is not supplied, the current-input-port is used. +@end deffn + +@deffn primitive drain-input port +Drain @var{port}'s read buffers (including any pushed-back +characters) and return the content as a single string. +@end deffn + +@deffn primitive port-column port +@deffnx primitive port-line port +Return the current column number or line number of @var{port}, +using the current input port if none is specified. 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 primitive set-port-column! port column +@deffnx primitive set-port-line! port line +Set the current column or line number of @var{port}, using the +current input port if none is specified. +@end deffn + +@node Writing +@section Writing + +[Generic procedures for writing to ports.] + +@deffn primitive 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 newline +@deffn primitive newline [port] +Send a newline to @var{port}. +@end deffn + +@deffn primitive 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 primitive print-options-interface [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 primitive 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 primitive write-char chr [port] +Send character @var{chr} to @var{port}. +@end deffn + +@findex fflush +@deffn primitive 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 primitive flush-all-ports +Equivalent to calling @code{force-output} on +all open output ports. The return value is unspecified. +@end deffn + + +@node Closing +@section Closing + +@deffn primitive 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 + +@rnindex close-input-port +@deffn primitive close-input-port port +Close the specified input port object. The routine has no effect if +the file has already been closed. An exception may be raised if an +error occurs. The value returned is unspecified. + +See also @ref{Ports and File Descriptors, close}, for a procedure +which can close file descriptors. +@end deffn + +@rnindex close-output-port +@deffn primitive close-output-port port +Close the specified output port object. The routine has no effect if +the file has already been closed. An exception may be raised if an +error occurs. The value returned is unspecified. + +See also @ref{Ports and File Descriptors, close}, for a procedure +which can close file descriptors. +@end deffn + +@deffn primitive port-closed? port +Return @code{#t} if @var{port} is closed or @code{#f} if it is +open. +@end deffn + + +@node Random Access +@section Random Access + +@deffn primitive 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 primitive 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 primitive 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 +@section 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 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 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 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 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 primitive 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 primitive %read-delimited! 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 primitive %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 +@section 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 primitive read-string!/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 primitive 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 +@section Default Ports for Input, Output and Errors + +@rnindex current-input-port +@deffn primitive 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 primitive 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 primitive 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 primitive set-current-input-port port +@deffnx primitive set-current-output-port port +@deffnx primitive 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 + +@deffn primitive set-current-output-port port +Set the current default output port to PORT. +@end deffn + +@deffn primitive set-current-error-port port +Set the current default error port to PORT. +@end deffn + + +@node Port Types +@section 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 +@subsection 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. + +@deffn primitive 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 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 procedure open-output-file filename +Open @var{filename} for output. Equivalent to +@smalllisp +(open-file @var{filename} "w") +@end smalllisp +@end deffn + +@rnindex call-with-input-file +@deffn procedure call-with-input-file file proc +@var{proc} should be a procedure of one argument, and @var{file} should +be a string naming a file. The file must already exist. These +procedures call @var{proc} with one argument: the port obtained by +opening the named file for input or output. If the file cannot be +opened, an error is signalled. If the procedure returns, then the port +is closed automatically and the value yielded by the procedure is +returned. If the procedure does not return, then the port will not be +closed automatically unless it is possible to prove that the port will +never again be used for a read or write operation. +@end deffn + +@rnindex call-with-output-file +@deffn procedure call-with-output-file file proc +@var{proc} should be a procedure of one argument, and @var{file} should +be a string naming a file. The behaviour is unspecified if the file +already exists. These procedures call @var{proc} with one argument: the +port obtained by opening the named file for input or output. If the +file cannot be opened, an error is signalled. If the procedure returns, +then the port is closed automatically and the value yielded by the +procedure is returned. If the procedure does not return, then the port +will not be closed automatically unless it is possible to prove that the +port will never again be used for a read or write operation. +@end deffn + +@rnindex with-input-from-file +@deffn procedure with-input-from-file file thunk +@var{thunk} must be a procedure of no arguments, and @var{file} must be +a string naming a file. The file must already exist. The file is opened +for input, an input port connected to it is made the default value +returned by @code{current-input-port}, and the @var{thunk} is called +with no arguments. When the @var{thunk} returns, the port is closed and +the previous default is restored. Returns the value yielded by +@var{thunk}. If an escape procedure is used to escape from the +continuation of these procedures, their behavior is implementation +dependent. +@end deffn + +@rnindex with-output-to-file +@deffn procedure with-output-to-file file thunk +@var{thunk} must be a procedure of no arguments, and @var{file} must be +a string naming a file. The effect is unspecified if the file already +exists. The file is opened for output, an output port connected to it +is made the default value returned by @code{current-output-port}, and +the @var{thunk} is called with no arguments. When the @var{thunk} +returns, the port is closed and the previous default is restored. +Returns the value yielded by @var{thunk}. If an escape procedure is +used to escape from the continuation of these procedures, their behavior +is implementation dependent. +@end deffn + +@deffn procedure with-error-to-file file thunk +@var{thunk} must be a procedure of no arguments, and @var{file} must be +a string naming a file. The effect is unspecified if the file already +exists. The file is opened for output, an output port connected to it +is made the default value returned by @code{current-error-port}, and the +@var{thunk} is called with no arguments. When the @var{thunk} returns, +the port is closed and the previous default is restored. Returns the +value yielded by @var{thunk}. If an escape procedure is used to escape +from the continuation of these procedures, their behavior is +implementation dependent. +@end deffn + +@deffn primitive port-mode port +Returns 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 primitive 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 primitive set-port-filename! 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 primitive file-port? obj +Determine whether @var{obj} is a port that is related to a file. +@end deffn + + +@node String Ports +@subsection String Ports + +The following allow string ports to be opened by analogy to R4R* +file port facilities: + +@deffn primitive 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. +@end deffn + +@deffn primitive 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 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 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 primitive 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 primitive 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 primitive 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. +@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 +@subsection 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 primitive 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. 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) +@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 +@subsection 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 primitive %make-void-port mode +Create and return a new void port. A void port acts like +@code{/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 + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-memory.texi b/doc/ref/scheme-memory.texi new file mode 100644 index 000000000..6a1f21e9c --- /dev/null +++ b/doc/ref/scheme-memory.texi @@ -0,0 +1,222 @@ +@page +@node Memory Management +@chapter Memory Management and Garbage Collection + +@menu +* Garbage Collection:: +* Weak References:: +* Guardians:: +@end menu + + +@node Garbage Collection +@section Garbage Collection + +[FIXME: this is pasted in from Tom Lord's original guile.texi and should +be reviewed] + +@deffn primitive gc +Scans all of SCM objects and reclaims for further use those that are +no longer accessible. +@end deffn + +@deffn primitive gc-stats +Return an association list of statistics about Guile's current +use of storage. +@end deffn + +@deffn primitive object-address obj +Return an integer that for the lifetime of @var{obj} is uniquely +returned by this function for @var{obj} +@end deffn + +@deffn primitive unhash-name name +Flushes the glocs for @var{name}, or all glocs if @var{name} +is @code{#t}. +@end deffn + + +@node Weak References +@section Weak References + +[FIXME: This chapter is based on Mikael Djurfeldt's answer to a question +by Michael Livshin. Any mistakes are not theirs, of course. ] + +Weak references let you attach bookkeeping information to data so that +the additional information automatically disappears when the original +data is no longer in use and gets garbage collected. In a weak key hash, +the hash entry for that key disappears as soon as the key is no longer +referneced from anywhere else. For weak value hashes, the same happens +as soon as the value is no longer in use. Entries in a doubly weak hash +disappear when either the key or the value are not used anywhere else +anymore. + +Property lists offer the same kind of functionality as weak key hashes +in many situations. (@pxref{Property Lists}) + +Here's an example (a little bit strained perhaps, but one of the +examples is actually used in Guile): + +Assume that you're implementing a debugging system where you want to +associate information about filename and position of source code +expressions with the expressions themselves. + +Hashtables can be used for that, but if you use ordinary hash tables +it will be impossible for the scheme interpreter to "forget" old +source when, for example, a file is reloaded. + +To implement the mapping from source code expressions to positional +information it is necessary to use weak-key tables since we don't want +the expressions to be remembered just because they are in our table. + +To implement a mapping from source file line numbers to source code +expressions you would use a weak-value table. + +To implement a mapping from source code expressions to the procedures +they constitute a doubly-weak table has to be used. + +@menu +* Weak key hashes:: +* Weak vectors:: +@end menu + + +@node Weak key hashes +@subsection Weak key hashes + +@deffn primitive make-weak-key-hash-table size +@deffnx primitive make-weak-value-hash-table size +@deffnx primitive 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 primitive weak-key-hash-table? obj +@deffnx primitive weak-value-hash-table? obj +@deffnx primitive doubly-weak-hash-table? 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 primitive make-weak-value-hash-table k +@end deffn + +@deffn primitive weak-value-hash-table? x +@end deffn + +@deffn primitive make-doubly-weak-hash-table k +@end deffn + +@deffn primitive doubly-weak-hash-table? x +@end deffn + + +@node Weak vectors +@subsection Weak vectors + +Weak vectors are mainly useful in Guile's implementation of weak hash +tables. + +@deffn primitive 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 primitive weak-vector . l +@deffnx primitive list->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 primitive weak-vector? obj +Return @code{#t} if @var{obj} is a weak vector. Note that all +weak hashes are also weak vectors. +@end deffn + + +@node Guardians +@section Guardians + +@deffn primitive make-guardian [greedy?] +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 primitive destroy-guardian! 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 primitive guardian-greedy? guardian +Return @code{#t} if @var{guardian} is a greedy guardian, otherwise @code{#f}. +@end deffn + +@deffn primitive guardian-destroyed? guardian +Return @code{#t} if @var{guardian} has been destroyed, otherwise @code{#f}. +@end deffn + + +@page +@node Objects +@chapter Objects + +@deffn primitive entity? obj +Return @code{#t} if @var{obj} is an entity. +@end deffn + +@deffn primitive operator? obj +Return @code{#t} if @var{obj} is an operator. +@end deffn + +@deffn primitive set-object-procedure! obj proc +Return the object procedure of @var{obj} to @var{proc}. +@var{obj} must be either an entity or an operator. +@end deffn + +@deffn primitive 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 primitive 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/scheme-modules.texi b/doc/ref/scheme-modules.texi new file mode 100644 index 000000000..c0b37bc3c --- /dev/null +++ b/doc/ref/scheme-modules.texi @@ -0,0 +1,826 @@ +@page +@node Modules +@chapter 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 + +@menu +* Scheme and modules:: How modules are handled in standard Scheme. +* The Guile module system:: How Guile does it. +* Dynamic Libraries:: Loading libraries of compiled code at run time. +@end menu + + +@node Scheme and modules +@section Scheme and modules + +Scheme, as defined in R5RS, does @emph{not} have a module system at all. + +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. + + +@node The Guile module system +@section The Guile module system + +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 Guile version 1.4. +@c fixme: Actually, was it available before? 1.4 seems a bit late... + +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. +@c fixme: Review: Need better C code interface commentary. + +@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. +* More Module Procedures:: Low-level module code. +* Module System Quirks:: Strange things to be aware of. +* Included Guile Modules:: Which modules come with Guile? +@end menu + +@node General Information about Modules +@subsection General Information about Modules + +A Guile module is a collection of named procedures, variables and +macros, altogether called the @dfn{bindings}, since they bind, or +associate, a symbol (the name) to a Scheme object (procedure, variable, +or macro). 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} (REFFIXME). The resulting file name is then +searched in all directories in the variable @code{%load-path}. For +example, the @code{(ice-9 popen)} module would result in the filename +@code{ice-9/popen.scm} and searched in the installation directory 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 +@subsection 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 (REFFIXME %load-path). + +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) + :rename (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}. + +@c begin (scm-doc-string "boot-9.scm" "symbol-prefix-proc") +@deffn 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] [:rename 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{:rename} 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 + + +@node Creating Guile Modules +@subsection 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 More Module Procedures +@subsection More Module Procedures + +@c FIXME::martin: Review me! + +@c FIXME::martin: Should this procedure be documented and supported +@c at all? + +The procedures in this section are useful if you want to dig into the +innards of Guile's module system. If you don't know precisely what you +do, you should probably avoid using any of them. + +@deffn primitive standard-eval-closure module +Return an eval closure for the module @var{module}. +@end deffn + + +@node Module System Quirks +@subsection 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 +@subsection 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{Debugger User Interface}). + +@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 (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 +packge Jacal from Guile (@pxref{JACAL}). +@end table + + +@node Dynamic Libraries +@section 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 +@subsection Low level dynamic linking + +When using the low level procedures to do your dynamic linking, you have +complete control over which library is loaded when and what get's done +with it. + +@deffn primitive 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 primitive dynamic-object? val +Determine whether @var{val} represents a dynamically linked object file. +@end deffn + +@deffn primitive dynamic-unlink dynobj +Unlink the indicated object file from the application. The argument +@var{dynobj} should be one of the values returned by +@code{dynamic-link}. When @code{dynamic-unlink} has been called on +@var{dynobj}, it is no longer usable as an argument to the functions +below and you will get type mismatch errors when you try to. +@end deffn + +@deffn primitive dynamic-func function dynobj +Search the C function indicated by @var{function} (a string or symbol) +in @var{dynobj} and return some Scheme object that can later be used +with @code{dynamic-call} to actually call this function. Right now, +these Scheme objects are formed by casting the address of the function +to @code{long} and converting this number to its Scheme representation. + +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 primitive dynamic-call function dynobj +Call the C function indicated by @var{function} and @var{dynobj}. 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{dynobj}. When @var{function} is a string (or +symbol, etc.), look it up in @var{dynobj}; this is equivalent to + +@smallexample +(dynamic-call (dynamic-func @var{function} @var{dynobj} #f)) +@end smallexample + +Interrupts are deferred while the C function is executing (with +@code{SCM_DEFER_INTS}/@code{SCM_ALLOW_INTS}). +@end deffn + +@deffn primitive dynamic-args-call function dynobj args +Call the C function indicated by @var{function} and @var{dynobj}, 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 +@subsection Putting Compiled Code into Modules + +@c FIXME::martin: Change all gh_ references to their scm_ equivalents. + +The new primitives that you add to Guile with @code{gh_new_procedure} +or with any of the other mechanisms are normally placed into the same +module as all the other builtin procedures (like @code{display}). +However, it is also possible to put new primitives into their own +module. + +The mechanism for doing so is not very well thought out and is likely to +change when the module system of Guile itself is revised, but it is +simple and useful enough to document it as it stands. + +What @code{gh_new_procedure} 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{gh_new_procedure} for our new primitives. +Unfortunately, there is not yet an easy way to access the module system +from C, so we are better off with a more indirect approach. Instead of +adding our primitives at initialization time we merely register with +Guile that we are ready to provide the contents of a certain module, +should it ever be needed. + +@deftypefun void scm_register_module_xxx (char *@var{name}, void (*@var{initfunc})(void)) +Register with Guile that @var{initfunc} will provide the contents of the +module @var{name}. + +The function @var{initfunc} should perform the usual initialization +actions for your new primitives, like calling @code{gh_new_procedure} or +including the file produced by the snarfer. When @var{initfunc} is +called, the current module is a newly created module with a name as +indicated by @var{name}. Each definition that is added to it will be +automatically exported. + +The string @var{name} indicates the hierachical name of the new module. +It should consist of the individual components of the module name +separated by single spaces. That is, the Scheme module name @code{(foo +bar)}, which is a list, should be written as @code{"foo bar"} for the +@var{name} parameter. + +You can call @code{scm_register_module_xxx} at any time, even before +Guile has been initialized. This might be useful when you want to put +the call to it in some initialization code that is magically called +before main, like constructors for global C++ objects. + +An example for @code{scm_register_module_xxx} appears in the next section. +@end deftypefun + +Now, instead of calling the initialization function at program startup, +you should simply call @code{scm_register_module_xxx} and pass it the +initialization function. When the named module is later requested by +Scheme code with @code{use-modules} for example, Guile will notice that +it knows how to create this module and will call the initialization +function at the right time in the right context. + +@node Dynamic Linking and Compiled Code Modules +@subsection 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, tho. + +@c FIXME::martin: Change all gh_ references to their scm_ equivalents. + +@smallexample +#include <math.h> +#include <guile/gh.h> + +SCM +j0_wrapper (SCM x) +@{ + return gh_double2scm (j0 (gh_scm2double (x))); +@} + +void +init_math_bessel () +@{ + gh_new_procedure1_0 ("j0", 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{} the-root-module: 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{gh_new_procedure} is called. To put @code{j0} into its +own module named @samp{(math bessel)}, we need to make a call to +@code{scm_register_module_xxx}. Additionally, to have Guile perform +the dynamic linking automatically, we need to put @file{libbessel.so} +into a place where Guile can find it. The call to +@code{scm_register_module_xxx} should be contained in 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 add the following code to +@file{bessel.c}: + +@smallexample +void scm_init_math_bessel_module () +@{ + scm_register_module_xxx ("math bessel", init_math_bessel); +@} +@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}. It should call +@code{scm_register_module_xxx} with the correct module name and the +appropriate initialization function. When that initialization function +will be called, a newly created module with the right name will be the +@emph{current module} so that all definitions that the initialization +functions makes will end up in the correct module. + +After @file{libbessel.so} has been rebuild, we need to place the shared +library into the right place. When Guile tries to autoload the +@samp{(math bessel)} module, it looks not only for a file called +@file{math/bessel.scm} in its @code{%load-path}, but also for +@file{math/libbessel.so}. So all we need to do is to create a directory +called @file{math} somewhere in Guile's @code{%load-path} and place +@file{libbessel.so} there. Normally, the current directory @file{.} is +in the @code{%load-path}, so we just use that for this example. + +@smallexample +% mkdir maths +% cd maths +% ln -s ../libbessel.so . +% cd .. +% guile +guile> (use-modules (math bessel)) +guile> (j0 2) +0.223890779141236 +guile> (apropos 'j0) +@print{} bessel: j0 #<primitive-procedure j0> +@end smallexample + +That's it! + +Note that we used a symlink to make @file{libbessel.so} appear in the +right spot. This is probably not a bad idea in general. The +directories that the @file{%load-path} normally contains are supposed to +contain only architecture independent files. They are not really the +right place for a shared library. You might want to install the +libraries somewhere below @samp{exec_prefix} and then symlink to them +from the architecture independent directory. This will at least work on +heterogenous systems where the architecture dependent stuff resides in +the same place on all machines (which seems like a good idea to me +anyway). + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-options.texi b/doc/ref/scheme-options.texi new file mode 100644 index 000000000..d591008fe --- /dev/null +++ b/doc/ref/scheme-options.texi @@ -0,0 +1,398 @@ +@page +@node Options and Config +@chapter Runtime Options and Configuration + +Guile's 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 +* General option interface:: +* Reader options:: +* Printing options:: +* Debugger options:: +* Evaluator options:: +* Evaluator trap options:: +* Examples of option use:: +* Install Config:: Installation and configuration data. +@end menu + +@node General option interface +@section General option interface + +We will use the expression @code{<group>} to represent @code{read}, +@code{print}, @code{debug} or @code{evaluator}. + +@subheading Low level + +@c NJFIXME +@deffn primitive <group>-options-interface +@deffnx primitive read-options-interface [SOME-INT] +@deffnx primitive print-options-interface [SOME-INT] +@deffnx primitive evaluator-traps-interface [SOME-INT] +@deffnx primitive read-options-interface [SOME-INT] +[FIXME: I have just taken the comments for C routine scm_options that +implements all of these. It needs to be presented better.] + +If scm_options is called without arguments, the current option setting +is returned. If the argument is an option setting, options are altered +and the old setting is returned. If the argument isn't a list, a list +of sublists is returned, where each sublist contains option name, value +and documentation string. +@end deffn + + +@subheading User level + +@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 procedure <group>-options [arg] +@deffnx procedure read-options [arg] +@deffnx procedure print-options [arg] +@deffnx procedure debug-options [arg] +@deffnx 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 procedure <group>-enable option-symbol +@deffnx procedure read-enable option-symbol +@deffnx procedure print-enable option-symbol +@deffnx procedure debug-enable option-symbol +@deffnx 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 procedure <group>-disable option-symbol +@deffnx procedure read-disable option-symbol +@deffnx procedure print-disable option-symbol +@deffnx procedure debug-disable option-symbol +@deffnx 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 +@section 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 +@section 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 +@section 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 +@section 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 +@section 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 + + +@node Examples of option use +@section 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 + + +@node Install Config +@section Installation and Configuration Data + +It is often useful to have site-specific information about the current +Guile installation. This chapter describes how to find out about +Guile's configuration at run time. + +@deffn primitive version +@deffnx primitive major-version +@deffnx primitive minor-version +@deffnx primitive micro-version +Return a string describing Guile's version number, or its major or minor +version numbers, respectively. + +@lisp +(version) @result{} "1.6.5" +(major-version) @result{} "1" +(minor-version) @result{} "6" +(micro-version) @result{} "5" +@end lisp +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive libguile-config-stamp +Return a string describing the date on which @code{libguile} was +configured. This is used to determine whether the Guile core +interpreter and the ice-9 runtime have grown out of date with one +another. +@end deffn + +@deffn primitive %package-data-dir +Return the name of the directory where Scheme packages, modules and +libraries are kept. On most Unix systems, this will be +@samp{/usr/local/share/guile}. +@end deffn + +@deffn primitive %library-dir +Return the directory where the Guile Scheme library files are installed. +E.g., may return "/usr/share/guile/1.3.5". +@end deffn + +@deffn primitive %site-dir +Return the directory where the Guile site files are installed. +E.g., may return "/usr/share/guile/site". +@end deffn + +@deffn primitive 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 primitive 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 %load-path +Return the list of directories which should be searched for Scheme +modules and libraries. +@end defvar + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-procedures.texi b/doc/ref/scheme-procedures.texi new file mode 100644 index 000000000..b6886a325 --- /dev/null +++ b/doc/ref/scheme-procedures.texi @@ -0,0 +1,778 @@ +@page +@node Procedures and Macros +@chapter Procedures and Macros + +@menu +* Lambda:: Basic procedure creation using lambda. +* Optional Arguments:: Handling keyword, optional and rest arguments. +* Procedure Properties:: Procedure properties and metainformation. +* 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 +@section Lambda: Basic Procedure Creation + +@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 variablesm 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 + +@var{body} is a sequence of Scheme expressions which are evaluated in +order when the procedure is invoked. +@end deffn + + +@node Optional Arguments +@section Optional Arguments + +@c FIXME::martin: Review me! + +Scheme procedures, as defined in R5RS, can wither 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: + +@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 +@subsection 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 {libary 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 +left unbound 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 +@subsection 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 +@subsection 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 occurences, one or more occurences, and one +or zero occurences. + +@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 +paramater 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 +unbound in the procedure. This can be checked with the @code{bound?} +macro (documented below). + +@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 + +@deffn {library syntax} bound? variable +Check if a variable is bound in the current environment. + +The procedure @code{defined?} doesn't quite cut it as it stands, since +it only checks bindings in the top-level environment, not those in local +scope only. +@end deffn + + +@node define* Reference +@subsection 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 +agument @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 paramter 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 +@section Procedure Properties and Metainformation + +@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 metainformation 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 primitive procedure? obj +Return @code{#t} if @var{obj} is a procedure. +@end deffn + +@deffn primitive closure? obj +Return @code{#t} if @var{obj} is a closure. +@end deffn + +@deffn primitive thunk? 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 primitive procedure-properties proc +Return @var{obj}'s property list. +@end deffn + +@deffn primitive procedure-property p k +Return the property of @var{obj} with name @var{key}. +@end deffn + +@deffn primitive set-procedure-properties! proc new_val +Set @var{obj}'s property list to @var{alist}. +@end deffn + +@deffn primitive set-procedure-property! p k v +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 primitive 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 primitive set-source-properties! obj plist +Install the association list @var{plist} as the source property +list for @var{obj}. +@end deffn + +@deffn primitive set-source-property! 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 primitive source-properties obj +Return the source property association list of @var{obj}. +@end deffn + + +@deffn primitive 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 +@section 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 accesor 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 primitive 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 primitive procedure-with-setter? obj +Return @code{#t} if @var{obj} is a procedure with an +associated setter procedure. +@end deffn + +@deffn primitive procedure proc +Return the procedure of @var{proc}, which must be either a +procedure with setter, or an operator struct. +@end deffn + +@deffn primitive setter proc +Return the setter of @var{proc}, which must be either a procedure with +setter or an operator struct. +@end deffn + + +@node Macros +@section 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 +@section The R5RS @code{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 + +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-modules (ice-9 syncase))} or +@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 use one of the keywords +@code{#:use-module} and @code{#:use-syntax} 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 +@subsection The @code{syntax-rules} Pattern Language + + +@node Define-Syntax +@subsection 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 +@subsection Local Syntax Definitions + + +@node Syntax Case +@section Support for the @code{syntax-case} System + + + +@node Internal Macros +@section Internal Representation of Macros and Syntax + +Internally, Guile uses three different flavours of macros. The three +flavours 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 flavour 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 primitive procedure->syntax 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 primitive procedure->macro 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 primitive procedure->memoizing-macro 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} flavour macros are referred to +as @dfn{syntax transformers}. + +@deffn primitive macro? obj +Return @code{#t} if @var{obj} is a regular macro, a memoizing macro or a +syntax transformer. +@end deffn + +@deffn primitive 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 primitive macro-name m +Return the name of the macro @var{m}. +@end deffn + +@deffn primitive macro-transformer m +Return the transformer of the macro @var{m}. +@end deffn + +@deffn primitive 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/scheme-reading.texi b/doc/ref/scheme-reading.texi new file mode 100644 index 000000000..eea049d2d --- /dev/null +++ b/doc/ref/scheme-reading.texi @@ -0,0 +1,27 @@ +@page +@node Further Reading +@chapter Further Reading + +@itemize @bullet +@item +Dorai Sitaram's online Scheme tutorial, @dfn{Teach Yourself Scheme in +Fixnum Days}, at +@url{http://www.cs.rice.edu/~dorai/t-y-scheme/t-y-scheme.html}. +Includes a nice explanation of continuations. + +@item +@url{http://wombat.doc.ic.ac.uk/foldoc/}. + +@item +The complete text of @dfn{Structure and Interpretation of Computer +Programs}, the classic introduction to computer science and Scheme by +Hal Abelson, Jerry Sussman and Julie Sussman, is now available online at +@url{http://mitpress.mit.edu/sicp/sicp.html}. This site also provides +teaching materials related to the book, and all the source code used in +the book, in a form suitable for loading and running. +@end itemize + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-scheduling.texi b/doc/ref/scheme-scheduling.texi new file mode 100644 index 000000000..e2cdd3d2a --- /dev/null +++ b/doc/ref/scheme-scheduling.texi @@ -0,0 +1,435 @@ +@page +@node Scheduling +@chapter 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:: Dynamically scoped variables. +@end menu + + +@node Arbiters +@section 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 primitive 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 primitive try-arbiter arb +Return @code{#t} and lock the arbiter @var{arb} if the arbiter +was unlocked. Otherwise, return @code{#f}. +@end deffn + +@deffn primitive 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 +@section Asyncs + +@cindex asyncs +@cindex system asyncs + +@c FIXME::martin: Review me! + +An async is a pair of one thunk (a parameterless procedure) and a mark. +Setting the mark on an async guarantees that the thunk will be executed +somewhen in the future (@dfn{asynchronously}). Setting the mark more +than once is satisfied by one execution of the thunk. + +Guile supports two types of asyncs: Normal asyncs and system asyncs. +They differ in that marked system asyncs are executed implicitly as soon +as possible, whereas normal asyncs have to be invoked explicitly. +System asyncs are held in an internal data structure and are maintained +by Guile. + +Normal asyncs are created with @code{async}, system asyncs with +@code{system-async}. They are marked with @code{async-mark} or +@code{system-async-mark}, respectively. + +@deffn primitive async thunk +Create a new async for the procedure @var{thunk}. +@end deffn + +@deffn primitive system-async thunk +Create a new async for the procedure @var{thunk}. Also +add it to the system's list of active async objects. +@end deffn + +@deffn primitive async-mark a +Mark the async @var{a} for future execution. +@end deffn + +@deffn primitive system-async-mark a +Mark the async @var{a} for future execution. +@end deffn + +As already mentioned above, system asyncs are executed automatically. +Normal asyncs have to be explicitly invoked by storing one or more of +them into a list and passing them to @code{run-asyncs}. + +@deffn primitive run-asyncs list_of_a +Execute all thunks from the asyncs of the list @var{list_of_a}. +@end deffn + +Automatic invocation of system asyncs can be temporarily disabled by +calling @code{mask-signals} and @code{unmask-signals}. Setting the mark +while async execution is disabled will nevertheless cause the async to +run once execution is enabled again. Please note that calls to these +procedures should always be paired, and they must not be nested, e.g. no +@code{mask-signals} is allowed if another one is still active. + +@deffn primitive mask-signals +Mask signals. The returned value is not specified. +@end deffn + +@deffn primitive unmask-signals +Unmask signals. The returned value is not specified. +@end deffn + +@c FIXME::martin: Find an example for usage of `noop'. What is that +@c procedure for anyway? + +@deffn primitive noop . args +Do nothing. When called without arguments, return @code{#f}, +otherwise return the first argument. +@end deffn + + +@node Dynamic Roots +@section 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 primitive 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 primitive 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 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 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 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 +@section Threads +@cindex threads +@cindex Guile threads + +@strong{[NOTE: this chapter was written for Cygnus Guile and has not yet +been updated for the Guile 1.x release.]} + +Here is a the reference for Guile's threads. In this chapter I simply +quote verbatim Tom Lord's description of the low-level primitives +written in C (basically an interface to the POSIX threads library) and +Anthony Green's description of the higher-level thread procedures +written in scheme. +@cindex posix threads +@cindex Lord, Tom +@cindex Green, Anthony + +When using Guile threads, keep in mind that each guile thread is +executed in a new dynamic root. + +@menu +* Low level thread primitives:: +* Higher level thread procedures:: +@end menu + + +@node Low level thread primitives +@subsection 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 primitive 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 describing the condition. [Error codes are currently +meaningless integers. In the future, real values will be specified.] +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 primitive 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 primitive yield +If one or more threads are waiting to execute, calling yield forces an +immediate context switch to one of them. Otherwise, yield has no effect. +@end deffn + +@c begin (texi-doc-string "guile" "make-mutex") +@deffn primitive make-mutex +Create a new mutex object. +@end deffn + +@c begin (texi-doc-string "guile" "lock-mutex") +@deffn primitive 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}. +@end deffn + +@c begin (texi-doc-string "guile" "unlock-mutex") +@deffn primitive 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. +@end deffn + +@c begin (texi-doc-string "guile" "make-condition-variable") +@deffn primitive make-condition-variable +@end deffn + +@c begin (texi-doc-string "guile" "wait-condition-variable") +@deffn primitive wait-condition-variable cond-var mutex +@end deffn + +@c begin (texi-doc-string "guile" "signal-condition-variable") +@deffn primitive signal-condition-variable cond-var +@end deffn + + +@node Higher level thread procedures +@subsection 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 primitive %thread-handler tag args@dots{} + +This procedure is specified as the standard error-handler for +@code{make-thread} and @code{begin-thread}. If the number of @var{args} +is three or more, use @code{display-error}, otherwise display a message +"uncaught throw to @var{tag}". All output is sent to the port specified +by @code{current-error-port}. + +Before display, global var @code{the-last-stack} is set to @code{#f} +and signals are unmasked with @code{unmask-signals}. + +[FIXME: Why distinguish based on number of args?! Cue voodoo music here.] +@end deffn + +@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 @code{%thread-handler} as the error +handler. +@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 @code{%thread-handler} as the error +handler. +@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 first [rest@dots{}] +Evaluate forms @var{first} and @var{rest} under a newly created +anonymous mutex, using @code{with-mutex}. + +[FIXME: Is there any way to access the mutex?] +@end deffn + + +@node Fluids +@section Fluids + +@cindex fluids + +@c FIXME::martin: Review me! + +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 dynamically scoped variables. These are +used in several (especially in older) dialects of lisp, such as in Emacs +Lisp, and they work a bit like global variables in that they can be +modified by the caller of a procedure, and the called procedure will see +the changes. With lexically scoped variables---which are normally used +in Scheme---this cannot happen. 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. + +@deffn primitive 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 primitive fluid? obj +Return @code{#t} iff @var{obj} is a fluid; otherwise, return +@code{#f}. +@end deffn + +The values stored in a fluid can be accessed with @code{fluid-ref} and +@code{fluid-set!}. + +@deffn primitive 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 primitive fluid-set! 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 primitive 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 +one after another. @var{thunk} must be a procedure with no argument. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-translation.texi b/doc/ref/scheme-translation.texi new file mode 100644 index 000000000..c01b1491a --- /dev/null +++ b/doc/ref/scheme-translation.texi @@ -0,0 +1,44 @@ +@page +@node Translation +@chapter Support for Translating Other Languages + +[Describe translation framework.] + +@menu +* Emacs Lisp Support:: Helper primitives for Emacs Lisp. +@end menu + + +@node Emacs Lisp Support +@section Emacs Lisp Support + +@deffn primitive 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 primitive 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 primitive 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 primitive 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 primitive 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/scheme-utility.texi b/doc/ref/scheme-utility.texi new file mode 100644 index 000000000..93c76bdf1 --- /dev/null +++ b/doc/ref/scheme-utility.texi @@ -0,0 +1,295 @@ +@page +@node Utility Functions +@chapter 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{utlity} chapter. + +@menu +* Equality:: When are two values `the same'? +* Property Lists:: Managing metainformation about Scheme objects. +* Primitive Properties:: A modern low-level interface to object properties. +* Sorting:: Sort utility procedures. +* Copying:: Copying deep structures. +* General Conversion:: Converting objects to strings. +@end menu + + +@node Equality +@section 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 primitive eq? 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 + +@rnindex eqv? +@deffn primitive eqv? 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 primitive equal? 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 Property Lists +@section Property Lists + +Every object in the system can have a @dfn{property list} that may +be used for information about that object. For example, a +function may have a property list that includes information about +the source file in which it is defined. + +Property lists are implemented as assq lists (@pxref{Association Lists}). + +Currently, property lists are implemented differently for procedures and +closures than for other kinds of objects. Therefore, when manipulating +a property list associated with a procedure object, use the +@code{procedure} functions; otherwise, use the @code{object} functions. + +@deffn primitive object-properties obj +@deffnx primitive procedure-properties obj +Return @var{obj}'s property list. +@end deffn + +@deffn primitive set-object-properties! obj alist +@deffnx primitive set-procedure-properties! obj alist +Set @var{obj}'s property list to @var{alist}. +@end deffn + +@deffn primitive object-property obj key +@deffnx primitive procedure-property obj key +Return the property of @var{obj} with name @var{key}. +@end deffn + +@deffn primitive set-object-property! obj key value +@deffnx primitive set-procedure-property! obj key value +In @var{obj}'s property list, set the property named @var{key} +to @var{value}. +@end deffn + +[Interface bug: there should be a second level of interface in which +the user provides a "property table" that is possibly private.] + + +@node Primitive Properties +@section Primitive Properties + +@deffn primitive 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 primitive 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}, call +@var{not-found-proc} instead (see @code{primitive-make-property}) +and use its return value. That value is also associated with +@var{obj} via @code{primitive-property-set!}. When +@var{not-found-proc} is @code{#f}, use @code{#f} as the +default value of @var{prop}. +@end deffn + +@deffn primitive primitive-property-set! prop obj val +Associate @var{code} with @var{prop} and @var{obj}. +@end deffn + +@deffn primitive primitive-property-del! prop obj +Remove any value associated with @var{prop} and @var{obj}. +@end deffn + + +@node Sorting +@section 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 primitive merge alist blist less +Take 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?)}. +@end deffn + +@deffn primitive merge! 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 primitive sorted? 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 primitive 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 primitive 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. 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 primitive 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 primitive 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. +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 primitive 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 primitive sort-list! 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 primitive restricted-vector-sort! 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 +@section 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 primitive 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 +@section 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 primitive object->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 + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scm.texi b/doc/ref/scm.texi new file mode 100644 index 000000000..c6a00d5c9 --- /dev/null +++ b/doc/ref/scm.texi @@ -0,0 +1,458 @@ +@page +@node Scheme Primitives +@c @chapter Writing Scheme primitives in C +@c - according to the menu in guile.texi - NJ 2001/1/26 +@chapter Relationship between Scheme and C functions + +@c Chapter contents contributed by Thien-Thi Nguyen <ttn@gnu.org>. + +Scheme procedures marked "primitive functions" have a regular interface +when calling from C, reflected in two areas: the name of a C function, and +the convention for passing non-required arguments to this function. + +@c Although the vast majority of functions support these relationships, +@c there are some exceptions. + +@menu +* Transforming Scheme name to C name:: +* Structuring argument lists for C functions:: +@c * Exceptions to the regularity:: +@end menu + +@node Transforming Scheme name to C name +@section Transforming Scheme name to C name + +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 "_p". + +@item +Replace @code{!} (exclamation point) with "_x". + +@item +Replace internal @code{->} with "_to_". + +@item +Replace @code{<=} (less than or equal) with "_leq". + +@item +Replace @code{>=} (greater than or equal) with "_geq". + +@item +Replace @code{<} (less than) with "_less". + +@item +Replace @code{>} (greater than) with "_gr". + +@item +Replace @code{@@} with "at". [Omit?] + +@item +Prefix with "gh_" (or "scm_" if you are ignoring the gh interface). + +@item +[Anything else? --ttn, 2000/01/16 15:17:28] + +@end itemize + +Here is an Emacs Lisp command that prompts for a Scheme function name and +inserts the corresponding C function name into the buffer. + +@example +(defun insert-scheme-to-C (name &optional use-gh) + "Transforms Scheme NAME, a string, to its C counterpart, and inserts it. +Prefix arg non-nil means use \"gh_\" prefix, otherwise use \"scm_\" prefix." + (interactive "sScheme name: \nP") + (let ((transforms '(("-" . "_") + ("?" . "_p") + ("!" . "_x") + ("->" . "_to_") + ("<=" . "_leq") + (">=" . "_geq") + ("<" . "_less") + (">" . "_gr") + ("@" . "at")))) + (while transforms + (let ((trigger (concat "\\(.*\\)" + (regexp-quote (caar transforms)) + "\\(.*\\)")) + (sub (cdar transforms)) + (m nil)) + (while (setq m (string-match trigger name)) + (setq name (concat (match-string 1 name) + sub + (match-string 2 name))))) + (setq transforms (cdr transforms)))) + (insert (if use-gh "gh_" "scm_") name)) +@end example + +@node Structuring argument lists for C functions +@section Structuring argument lists for C functions + +The C function's arguments will be all of the Scheme procedure's +argumements, both required and optional; if the Scheme procedure takes a +``rest'' argument, that will be a final argument to the C function. The +C function's arguments, as well as its return type, will be @code{SCM}. + +@c @node Exceptions to the regularity +@c @section Exceptions to the regularity +@c +@c There are some exceptions to the regular structure described above. + + +@page +@node I/O Extensions +@chapter 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 +@section C Port Interface + +This section describes how to use Scheme ports from C. + +@subsection 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. + +@subsection 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. + +@subsection 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 +implemention 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. + +@subsection 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 + +@subsection 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 + +@subsection 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 +@section 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} initialises three elements of the structure +(@code{name}, @code{fill_input} and @code{write}) from its arguments. +The remaining elements are initialised 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 synchronisation 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 + + +@node Handling Errors +@chapter How to Handle Errors in C Code + +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 primitive scm-error key subr message args rest +Throw an error, with arguments +as described above. +@end deffn + +@deffn procedure error msg arg @dots{} +Throw an error using the key @code{'misc-error}. The error +message is created by displaying @var{msg} and writing the @var{args}. +@end deffn + +The following are the error keys defined by libguile and the situations +in which they are used: + +@itemize @bullet +@item +@code{error-signal}: thrown after receiving an unhandled fatal signal +such as SIGSEV, 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 +@code{system-error}: thrown after the operating system indicates an +error condition. The @var{rest} argument in the throw contains the +errno value. + +@item +@code{numerical-overflow}: numerical overflow. + +@item +@code{out-of-range}: the arguments to a procedure do not fall within the +accepted domain. + +@item +@code{wrong-type-arg}: an argument to a procedure has the wrong thpe. + +@item +@code{wrong-number-of-args}: a procedure was called with the wrong number +of arguments. + +@item +@code{memory-allocation-error}: memory allocation error. + +@item +@code{stack-overflow}: stack overflow error. + +@item +@code{regex-error}: errors generated by the regular expression library. + +@item +@code{misc-error}: other errors. +@end itemize + + +@section C Support + +SCM scm_error (SCM key, char *subr, char *message, SCM args, SCM rest) + +Throws an error, after converting the char * arguments to Scheme strings. +subr is the Scheme name of the procedure, NULL is converted to #f. +Likewise a NULL message is converted to #f. + +The following procedures invoke scm_error with various error keys and +arguments. The first three call scm_error with the system-error key +and automatically supply errno in the "rest" argument: scm_syserror +generates messages using strerror, scm_sysmissing is used when +facilities are not available. Care should be taken that the errno +value is not reset (e.g. due to an interrupt). + +@itemize @bullet +@item +void scm_syserror (char *subr); +@item +void scm_syserror_msg (char *subr, char *message, SCM args); +@item +void scm_sysmissing (char *subr); +@item +void scm_num_overflow (char *subr); +@item +void scm_out_of_range (char *subr, SCM bad_value); +@item +void scm_wrong_num_args (SCM proc); +@item +void scm_wrong_type_arg (char *subr, int pos, SCM bad_value); +@item +void scm_memory_error (char *subr); +@item +static void scm_regex_error (char *subr, int code); (only used in rgx.c). +@end itemize + +Exception handlers can also be installed from C, using +scm_internal_catch, scm_lazy_catch, or scm_stack_catch from +libguile/throw.c. These have not yet been documented, however the +source contains some useful comments. diff --git a/doc/ref/script-getopt.texi b/doc/ref/script-getopt.texi new file mode 100644 index 000000000..474394af7 --- /dev/null +++ b/doc/ref/script-getopt.texi @@ -0,0 +1,435 @@ +@page +@node Command Line Handling +@chapter Handling Command Line Options and Arguments + +@c This chapter 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. + +@menu +* Command Line Args:: Using command line arguments. +* getopt-long:: The (ice-9 getopt-long) module. +@end menu + + +@node Command Line Args +@section Using 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. + + +@node getopt-long +@section The (ice-9 getopt-long) Module + +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. + +The @code{(ice-9 getopt-long)} module exports two procedures: +@code{getopt-long} and @code{option-ref}. + +@itemize @bullet +@item +@code{getopt-long} takes a list of strings --- the command line +arguments --- and an @dfn{option specification}. It parses the command +line arguments according to the option specification and returns a data +structure that encapsulates the results of the parsing. + +@item +@code{option-ref} then takes the parsed data structure and a specific +option's name, and returns information about that option in particular. +@end itemize + +To make these procedures available to your Guile script, include the +expression @code{(use-modules (ice-9 getopt-long))} somewhere near the +top, before the first usage of @code{getopt-long} or @code{option-ref}. + +@menu +* getopt-long Example:: A short getopt-long example. +* Option Specification:: How to write an option specification. +* Command Line Format:: The expected command line format. +* getopt-long Reference:: Full documentation for @code{getopt-long}. +* option-ref Reference:: Full documentation for @code{option-ref}. +@end menu + + +@node getopt-long Example +@subsection A Short getopt-long Example + +This subsection illustrates how @code{getopt-long} is used by presenting +and dissecting a simple example. The first thing that we need is an +@dfn{option specification} that tells @code{getopt-long} how to parse +the command line. This specification is an association list with the +long option name as the key. Here is how such a specification might +look: + +@lisp +(define option-spec + '((version (single-char #\v) (value #f)) + (help (single-char #\h) (value #f)))) +@end lisp + +This alist tells @code{getopt-long} that it should accept two long +options, called @emph{version} and @emph{help}, and that these options +can also be selected by the single-letter abbreviations @emph{v} and +@emph{h}, respectively. The @code{(value #f)} clauses indicate that +neither of the options accepts a value. + +With this specification we can use @code{getopt-long} to parse a given +command line: + +@lisp +(define options (getopt-long (command-line) option-spec)) +@end lisp + +After this call, @code{options} contains the parsed command line and is +ready to be examined by @code{option-ref}. @code{option-ref} is called +like this: + +@lisp +(option-ref options 'help #f) +@end lisp + +@noindent +It expects the parsed command line, a symbol indicating the option to +examine, and a default value. The default value is returned if the +option was not present in the command line, or if the option was present +but without a value; otherwise the value from the command line is +returned. Usually @code{option-ref} is called once for each possible +option that a script supports. + +The following example shows a main program which puts all this together +to parse its command line and figure out what the user wanted. + +@lisp +(define (main args) + (let* ((option-spec '((version (single-char #\v) (value #f)) + (help (single-char #\h) (value #f)))) + (options (getopt-long args option-spec)) + (help-wanted (option-ref options 'help #f)) + (version-wanted (option-ref options 'version #f))) + (if (or version-wanted help-wanted) + (begin + (if version-wanted + (display "getopt-long-example version 0.3\n")) + (if help-wanted + (display "\ +getopt-long-example [options] + -v, --version Display version + -h, --help Display this help +"))) + (begin + (display "Hello, World!") (newline))))) +@end lisp + + +@node Option Specification +@subsection How to Write an Option Specification + +An option specification is an association list (@pxref{Association +Lists}) with one list element for each supported option. The key of each +list element is a symbol that names the option, while the value is a +list of option properties: + +@lisp +OPTION-SPEC ::= '( (OPT-NAME1 (PROP-NAME PROP-VALUE) @dots{}) + (OPT-NAME2 (PROP-NAME PROP-VALUE) @dots{}) + (OPT-NAME3 (PROP-NAME PROP-VALUE) @dots{}) + @dots{} + ) +@end lisp + +Each @var{opt-name} specifies the long option name for that option. For +example, a list element with @var{opt-name} @code{background} specifies +an option that can be specified on the command line using the long +option @code{--background}. Further information about the option --- +whether it takes a value, whether it is required to be present in the +command line, and so on --- is specified by the option properties. + +In the example of the preceding subsection, we already saw that a long +option name can have a equivalent @dfn{short option} character. The +equivalent short option character can be set for an option by specifying +a @code{single-char} property in that option's property list. For +example, a list element like @code{'(output (single-char #\o) @dots{})} +specifies an option with long name @code{--output} that can also be +specified by the equivalent short name @code{-o}. + +The @code{value} property specifies whether an option requires or +accepts a value. If the @code{value} property is set to @code{#t}, the +option requires a value: @code{getopt-long} will signal an error if the +option name is present without a corresponding value. If set to +@code{#f}, the option does not take a value; in this case, a non-option +word that follows the option name in the command line will be treated as +a non-option argument. If set to the symbol @code{optional}, the option +accepts a value but does not require one: a non-option word that follows +the option name in the command line will be interpreted as that option's +value. If the option name for an option with @code{'(value optional)} +is immediately followed in the command line by @emph{another} option +name, the value for the first option is implicitly @code{#t}. + +The @code{required?} property indicates whether an option is required to +be present in the command line. If the @code{required?} property is +set to @code{#t}, @code{getopt-long} will signal an error if the option +is not specified. + +Finally, the @code{predicate} property can be used to constrain the +possible values of an option. If used, the @code{predicate} property +should be set to a procedure that takes one argument --- the proposed +option value as a string --- and returns either @code{#t} or @code{#f} +according as the proposed value is or is not acceptable. If the +predicate procedure returns @code{#f}, @code{getopt-long} will signal an +error. + +By default, options do not have single-character equivalents, are not +required, and do not take values. Where the list element for an option +includes a @code{value} property but no @code{predicate} property, the +option values are unconstrained. + + +@node Command Line Format +@subsection Expected Command Line Format + +In order for @code{getopt-long} to correctly parse a command line, that +command line must conform to a standard set of rules for how command +line options are specified. This subsection explains what those rules +are. + +@code{getopt-long} splits a given command line into several pieces. All +elements of the argument list are classified to be either options or +normal arguments. Options consist of two dashes and an option name +(so-called @dfn{long} options), or of one dash followed by a single +letter (@dfn{short} options). + +Options can behave as switches, when they are given without a value, or +they can be used to pass a value to the program. The value for an +option may be specified using an equals sign, or else is simply the next +word in the command line, so the following two invocations are +equivalent: + +@example +$ ./foo.scm --output=bar.txt +$ ./foo.scm --output bar.txt +@end example + +Short options can be used instead of their long equivalents and can be +grouped together after a single dash. For example, the following +commands are equivalent. + +@example +$ ./foo.scm --version --help +$ ./foo.scm -v --help +$ ./foo.scm -vh +@end example + +If an option requires a value, it can only be grouped together with other +short options if it is the last option in the group; the value is the +next argument. So, for example, with the following option +specification --- + +@lisp +((apples (single-char #\a)) + (blimps (single-char #\b) (value #t)) + (catalexis (single-char #\c) (value #t))) +@end lisp + +@noindent +--- the following command lines would all be acceptable: + +@example +$ ./foo.scm -a -b bang -c couth +$ ./foo.scm -ab bang -c couth +$ ./foo.scm -ac couth -b bang +@end example + +But the next command line is an error, because @code{-b} is not the last +option in its combination, and because a group of short options cannot +include two options that both require values: + +@example +$ ./foo.scm -abc couth bang +@end example + +If an option's value is optional, @code{getopt-long} decides whether the +option has a value by looking at what follows it in the argument list. +If the next element is a string, and it does not appear to be an option +itself, then that string is the option's value. + +If the option @code{--} appears in the argument list, argument parsing +stops there and subsequent arguments are returned as ordinary arguments, +even if they resemble options. So, with the command line + +@example +$ ./foo.scm --apples "Granny Smith" -- --blimp Goodyear +@end example + +@noindent +@code{getopt-long} will recognize the @code{--apples} option as having +the value "Granny Smith", but will not treat @code{--blimp} as an +option. The strings @code{--blimp} and @code{Goodyear} will be returned +as ordinary argument strings. + + +@node getopt-long Reference +@subsection Reference Documentation for @code{getopt-long} + +@deffn procedure getopt-long args grammar +Parse the command line given in @var{args} (which must be a list of +strings) according to the option specification @var{grammar}. + +The @var{grammar} argument is expected to be a list of this form: + +@code{((@var{option} (@var{property} @var{value}) @dots{}) @dots{})} + +where each @var{option} is a symbol denoting the long option, but +without the two leading dashes (e.g. @code{version} if the option is +called @code{--version}). + +For each option, there may be list of arbitrarily many property/value +pairs. The order of the pairs is not important, but every property may +only appear once in the property list. The following table lists the +possible properties: + +@table @asis +@item @code{(single-char @var{char})} +Accept @code{-@var{char}} as a single-character equivalent to +@code{--@var{option}}. This is how to specify traditional Unix-style +flags. +@item @code{(required? @var{bool})} +If @var{bool} is true, the option is required. @code{getopt-long} will +raise an error if it is not found in @var{args}. +@item @code{(value @var{bool})} +If @var{bool} is @code{#t}, the option accepts a value; if it is +@code{#f}, it does not; and if it is the symbol @code{optional}, the +option may appear in @var{args} with or without a value. +@item @code{(predicate @var{func})} +If the option accepts a value (i.e. you specified @code{(value #t)} for +this option), then @code{getopt-long} will apply @var{func} to the +value, and throw an exception if it returns @code{#f}. @var{func} +should be a procedure which accepts a string and returns a boolean +value; you may need to use quasiquotes to get it into @var{grammar}. +@end table +@end deffn + +@code{getopt-long}'s @var{args} parameter is expected to be a list of +strings like the one returned by @code{command-line}, with the first +element being the name of the command. Therefore @code{getopt-long} +ignores the first element in @var{args} and starts argument +interpretation with the second element. + +@code{getopt-long} signals an error if any of the following conditions +hold. + +@itemize @bullet +@item +The option grammar has an invalid syntax. + +@item +One of the options in the argument list was not specified by the +grammar. + +@item +A required option is omitted. + +@item +An option which requires an argument did not get one. + +@item +An option that doesn't accept an argument does get one (this can only +happen using the long option @code{--opt=@var{value}} syntax). + +@item +An option predicate fails. +@end itemize + + +@node option-ref Reference +@subsection Reference Documentation for @code{option-ref} + +@deffn procedure option-ref options key default +Search @var{options} for a command line option named @var{key} and +return its value, if found. If the option has no value, but was given, +return @code{#t}. If the option was not given, return @var{default}. +@var{options} must be the result of a call to @code{getopt-long}. +@end deffn + +@code{option-ref} always succeeds, either by returning the requested +option value from the command line, or the default value. + +The special key @code{'()} can be used to get a list of all +non-option arguments. + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scripts.texi b/doc/ref/scripts.texi new file mode 100644 index 000000000..e3f09f471 --- /dev/null +++ b/doc/ref/scripts.texi @@ -0,0 +1,213 @@ +@page +@node Guile Scripting +@chapter 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 +* Invoking Guile:: How to start a Guile script. +* The Meta Switch:: Passing complex argument lists to Guile + from shell scripts. +@end menu + +@node Invoking Guile +@section 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. + +@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 -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 +@section 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 diff --git a/doc/ref/scsh.texi b/doc/ref/scsh.texi new file mode 100644 index 000000000..99afc0406 --- /dev/null +++ b/doc/ref/scsh.texi @@ -0,0 +1,25 @@ +@page +@node The Scheme shell (scsh) +@chapter The Scheme shell (scsh) + +An incomplete port of the Scheme shell (scsh) 0.5.1 is available for +Guile. The idea is to allow Scheme code using scsh interfaces to be run +inside the Guile interpreter. + +For information about scsh on the Web see +@url{http://www-swiss.ai.mit.edu/scsh/scsh.html}. +The original scsh is available by ftp from +@url{ftp://swiss-ftp.ai.mit.edu:/pub/su}. + +The scsh code is distributed as a separate module, guile-scsh, +which must be installed somewhere in Guile's load path before +it can be used. This is similar to the installation +of slib (you may want to install that first, since it's needed before +scsh can run in Guile: see @ref{SLIB} for details). + +This port of scsh does not currently use the Guile module system, but +can be initialized with: + +@smalllisp +(load-from-path "scsh/init") +@end smalllisp diff --git a/doc/ref/slib.texi b/doc/ref/slib.texi new file mode 100644 index 000000000..445b084c6 --- /dev/null +++ b/doc/ref/slib.texi @@ -0,0 +1,105 @@ +@page +@node SLIB +@chapter SLIB + +Before the the SLIB facilities can be used, the following Scheme +expression must be executed: + +@smalllisp +(use-modules (ice-9 slib)) +@end smalllisp + +@code{require} can then be used as described in +@ref{Top, , SLIB, slib, The SLIB Manual}. + +For example: + +@smalllisp +guile> (use-modules (ice-9 slib)) +guile> (require 'primes) +guile> (probably-prime? 13) +@end smalllisp + +@menu +* SLIB installation:: +* JACAL:: +@end menu + +@node SLIB installation +@section SLIB installation + +The following seems to work, at least with slib 2c7: + +@enumerate +@item +Unpack slib somewhere, e.g., /usr/local/lib/slib. + +@item +Create a symlink in the Guile site directory to slib, e.g.,: + +@example +ln -s /usr/local/lib/slib /usr/local/share/guile/site/slib +@end example + +@item +Use Guile to create the catalogue file, e.g.,: + +@example +# guile +guile> (use-modules (ice-9 slib)) +guile> (load "/usr/local/lib/slib/mklibcat.scm") +guile> (quit) +@end example + +The catalogue data should now be in +@code{/usr/local/share/guile/site/slibcat}. + +If instead you get an error such as: + +@example +Unbound variable: scheme-implementation-type +@end example + +then a solution is to get a newer version of Guile, +or to modify ice-9/slib.scm to use define-public for the +offending variables. + +@item +Install the documentation: + +@example +cd /usr/local/lib/slib +rm /usr/local/info/slib.info* +cp slib.info /usr/local/info +install-info slib.info /usr/local/info/dir +@end example +@end enumerate + +@node JACAL +@section JACAL + +@cindex Jaffer, Aubrey +@cindex symbolic math +@cindex math -- symbolic +Jacal is a symbolic math package written in Scheme by Aubrey Jaffer. It +is usually installed as an extra package in SLIB (@pxref{Packages not +shipped with Guile}). + +You can use Guile's interface to SLIB to invoke Jacal: + +@smalllisp +(use-modules (ice-9 slib)) +(slib:load "math") +(math) +@end smalllisp + +@noindent +For complete documentation on Jacal, please read the Jacal manual. If +it has been installed on line, you can look at @ref{Top, , Jacal, jacal, +The SLIB Manual}. Otherwise you can find it on the web at +@url{http://www-swiss.ai.mit.edu/~jaffer/JACAL.html} + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi new file mode 100644 index 000000000..2f48f7dd1 --- /dev/null +++ b/doc/ref/srfi-modules.texi @@ -0,0 +1,2241 @@ +@page +@node SRFI Support +@chapter SRFI Support Modules + +SRFI is an acronym for Scheme Request For Implementation. The SRFI +documents define a lot of syntactic and procedure extensions to standard +Scheme as defined in R5RS. + +Guile has support for a number of SRFIs. This chapter gives an overview +over the available SRFIs and some usage hints. For complete +documentation, design rationales and further examples, we advise you to +get the relevant SRFI documents from the SRFI home page +@url{http://srfi.schemers.org}. + +@menu +* About SRFI Usage:: What to know about Guile's SRFI support. +* SRFI-0:: cond-expand +* SRFI-1:: List library. +* SRFI-2:: and-let*. +* SRFI-4:: Homogeneous numeric vector datatypes. +* SRFI-6:: Basic String Ports. +* SRFI-8:: receive. +* SRFI-9:: define-record-type. +* SRFI-10:: Hash-Comma Reader Extension. +* SRFI-11:: let-values and let-values*. +* SRFI-13:: String library. +* SRFI-14:: Character-set library. +* SRFI-16:: case-lambda +* SRFI-17:: Generalized set! +@end menu + + +@node About SRFI Usage +@section About SRFI Usage + +@c FIXME::martin: Review me! + +SRFI support in Guile is currently implemented partly in the core +library, and partly as add-on modules. That means that some SRFIs are +automatically available when the interpreter is started, whereas the +other SRFIs require you to use the appropriate support module +explicitly. + +There are several reasons for this inconsistency. First, the feature +checking syntactic form @code{cond-expand} (@pxref{SRFI-0}) must be +available immediately, because it must be there when the user wants to +check for the Scheme implementation, that is, before she can know that +it is safe to use @code{use-modules} to load SRFI support modules. The +second reason is that some features defined in SRFIs had been +implemented in Guile before the developers started to add SRFI +implementations as modules (for example SRFI-6 (@pxref{SRFI-6})). In +the future, it is possible that SRFIs in the core library might be +factored out into separate modules, requiring explicit module loading +when they are needed. So you should be prepared to have to use +@code{use-modules} someday in the future to access SRFI-6 bindings. If +you want, you can do that already. We have included the module +@code{(srfi srfi-6)} in the distribution, which currently does nothing, +but ensures that you can write future-safe code. + +Generally, support for a specific SRFI is made available by using +modules named @code{(srfi srfi-@var{number})}, where @var{number} is the +number of the SRFI needed. Another possibility is to use the command +line option @code{--use-srfi}, which will load the necessary modules +automatically (@pxref{Invoking Guile}). + + +@node SRFI-0 +@section SRFI-0 - cond-expand + +@c FIXME::martin: Review me! + +SRFI-0 defines a means for checking whether a Scheme implementation has +support for a specified feature. The syntactic form @code{cond-expand}, +which implements this means, has the following syntax. + +@example +@group +<cond-expand> + --> (cond-expand <cond-expand-clause>+) + | (cond-expand <cond-expand-clause>* (else <command-or-definition>)) +<cond-expand-clause> + --> (<feature-requirement> <command-or-definition>*) +<feature-requirement> + --> <feature-identifier> + | (and <feature-requirement>*) + | (or <feature-requirement>*) + | (not <feature-requirement>) +<feature-identifier> + --> <a symbol which is the name or alias of a SRFI> +@end group +@end example + +When evaluated, this form checks all clauses in order, until it finds +one whose feature requirement is satisfied. Then the form expands into +the commands or definitions in the clause. A requirement is tested as +follows: + +@itemize @bullet +@item +If it is a symbol, it is satisfied if the feature identifier is +supported. + +@item +If it is an @code{and} form, all requirements must be satisfied. If no +requirements are given, it is satisfied, too. + +@item +If it is an @code{or} form, at least one of the requirements must be +satisfied. If no requirements are given, it is not satisfied. + +@item +If it is a @code{not} form, the feature requirement must @emph{not} be +satisfied. + +@item +If the feature requirement is the keyword @code{else} and it is the last +clause, it is satisfied if no prior clause matched. +@end itemize + +If no clause is satisfied, an error is signalled. + +Since @code{cond-expand} is needed to tell what a Scheme implementation +provides, it must be accessible without using any +implementation-dependant operations, such as @code{use-modules} in +Guile. Thus, it is not necessary to use any module to get access to +this form. + +Currently, the feature identifiers @code{guile}, @code{r5rs} and +@code{srfi-0} are supported. The other SRFIs are not in that list by +default, because the SRFI modules must be explicitly used before their +exported bindings can be used. + +So if a Scheme program wishes to use SRFI-8, it has two possibilities: +First, it can check whether the running Scheme implementation is Guile, +and if it is, it can use the appropriate module: + +@lisp +(cond-expand + (guile + (use-modules (srfi srfi-8))) + (srfi-8 + #t)) + ;; otherwise fail. +@end lisp + +The other possibility is to use the @code{--use-srfi} command line +option when invoking Guile (@pxref{Invoking Guile}). When you do that, +the specified SRFI support modules will be loaded and add their feature +identifier to the list of symbols checked by @code{cond-expand}. + +So, if you invoke Guile like this: + +@example +$ guile --use-srfi=8 +@end example + +the following snippet will expand to @code{'hooray}. + +@lisp +(cond-expand (srfi-8 'hooray)) +@end lisp + + +@node SRFI-1 +@section SRFI-1 - List library + +@c FIXME::martin: Review me! + +The list library defined in SRFI-1 contains a lot of useful list +processing procedures for construction, examining, destructuring and +manipulating lists and pairs. + +Since SRFI-1 also defines some procedures which are already contained +in R5RS and thus are supported by the Guile core library, some list +and pair procedures which appear in the SRFI-1 document may not appear +in this section. So when looking for a particular list/pair +processing procedure, you should also have a look at the sections +@ref{Lists} and @ref{Pairs}. + +@menu +* SRFI-1 Constructors:: Constructing new lists. +* SRFI-1 Predicates:: Testing list for specific properties. +* SRFI-1 Selectors:: Selecting elements from lists. +* SRFI-1 Length Append etc:: Length calculation and list appending. +* SRFI-1 Fold and Map:: Higher-order list processing. +* SRFI-1 Filtering and Partitioning:: Filter lists based on predicates. +* SRFI-1 Searching:: Search for elments. +* SRFI-1 Deleting:: Delete elements from lists. +* SRFI-1 Association Lists:: Handle association lists. +* SRFI-1 Set Operations:: Use lists for representing sets. +@end menu + +@node SRFI-1 Constructors +@subsection Constructors + +@c FIXME::martin: Review me! + +New lists can be constructed by calling one of the following +procedures. + +@deffn procedure xcons d a +Like @code{cons}, but with interchanged arguments. Useful mostly when +passed to higher-order procedures. +@end deffn + +@deffn procedure list-tabulate n init-proc +Return an @var{n}-element list, where each list element is produced by +applying the procedure @var{init-proc} to the corresponding list +index. The order in which @var{init-proc} is applied to the indices +is not specified. +@end deffn + +@deffn procedure circular-list elt1 elt2 @dots{} +Return a circular list containing the given arguments @var{elt1} +@var{elt2} @dots{}. +@end deffn + +@deffn procedure iota count [start step] +Return a list containing @var{count} elements, where each element is +calculated as follows: + +@var{start} + (@var{count} - 1) * @var{step} + +@var{start} defaults to 0 and @var{step} defaults to 1. +@end deffn + + +@node SRFI-1 Predicates +@subsection Predicates + +@c FIXME::martin: Review me! + +The procedures in this section test specific properties of lists. + +@deffn procedure proper-list? obj +Return @code{#t} if @var{obj} is a proper list, that is a finite list, +terminated with the empty list. Otherwise, return @code{#f}. +@end deffn + +@deffn procedure circular-list? obj +Return @code{#t} if @var{obj} is a circular list, otherwise return +@code{#f}. +@end deffn + +@deffn procedure dotted-list? obj +Return @code{#t} if @var{obj} is a dotted list, return @code{#f} +otherwise. A dotted list is a finite list which is not terminated by +the empty list, but some other value. +@end deffn + +@deffn procedure null-list? lst +Return @code{#t} if @var{lst} is the empty list @code{()}, @code{#f} +otherwise. If something else than a proper or circular list is passed +as @var{lst}, an error is signalled. This procedure is recommented +for checking for the end of a list in contexts where dotted lists are +not allowed. +@end deffn + +@deffn procedure not-pair? obj +Return @code{#t} is @var{obj} is not a pair, @code{#f} otherwise. +This is shorthand notation @code{(not (pair? @var{obj}))} and is +supposed to be used for end-of-list checking in contexts where dotted +lists are allowed. +@end deffn + +@deffn procedure list= elt= list1 @dots{} +Return @code{#t} if all argument lists are equal, @code{#f} otherwise. +List equality is determined by testing whether all lists have the same +length and the corresponding elements are equal in the sense of the +equality predicate @var{elt=}. If no or only one list is given, +@code{#t} is returned. +@end deffn + + +@node SRFI-1 Selectors +@subsection Selectors + +@c FIXME::martin: Review me! + +@deffn procedure first pair +@deffnx procedure second pair +@deffnx procedure third pair +@deffnx procedure fourth pair +@deffnx procedure fifth pair +@deffnx procedure sixth pair +@deffnx procedure seventh pair +@deffnx procedure eighth pair +@deffnx procedure ninth pair +@deffnx procedure tenth pair +These are synonyms for @code{car}, @code{cadr}, @code{caddr}, @dots{}. +@end deffn + +@deffn procedure car+cdr pair +Return two values, the @sc{car} and the @sc{cdr} of @var{pair}. +@end deffn + +@deffn procedure take lst i +@deffnx procedure take! lst i +Return a list containing the first @var{i} elements of @var{lst}. + +@code{take!} may modify the structure of the argument list @var{lst} +in order to produce the result. +@end deffn + +@deffn procedure drop lst i +Return a list containing all but the first @var{i} elements of +@var{lst}. +@end deffn + +@deffn procedure take-right lst i +Return the a list containing the @var{i} last elements of @var{lst}. +@end deffn + +@deffn procedure drop-right lst i +@deffnx procedure drop-right! lst i +Return the a list containing all but the @var{i} last elements of +@var{lst}. + +@code{drop-right!} may modify the structure of the argument list +@var{lst} in order to produce the result. +@end deffn + +@deffn procedure split-at lst i +@deffnx procedure split-at! lst i +Return two values, a list containing the first @var{i} elements of the +list @var{lst} and a list containing the remaining elements. + +@code{split-at!} may modify the structure of the argument list +@var{lst} in order to produce the result. +@end deffn + +@deffn procedure last lst +Return the last element of the non-empty, finite list @var{lst}. +@end deffn + + +@node SRFI-1 Length Append etc +@subsection Length, Append, Concatenate, etc. + +@c FIXME::martin: Review me! + +@deffn procedure length+ lst +Return the length of the argument list @var{lst}. When @var{lst} is a +circular list, @code{#f} is returned. +@end deffn + +@deffn procedure concatenate list-of-lists +@deffnx procedure concatenate! list-of-lists +Construct a list by appending all lists in @var{list-of-lists}. + +@code{concatenate!} may modify the structure of the given lists in +order to produce the result. +@end deffn + +@deffn procedure append-reverse rev-head tail +@deffnx procedure append-reverse! rev-head tail +Reverse @var{rev-head}, append @var{tail} and return the result. This +is equivalent to @code{(append (reverse @var{rev-head}) @var{tail})}, +but more efficient. + +@code{append-reverse!} may modify @var{rev-head} in order to produce +the result. +@end deffn + +@deffn procedure zip lst1 lst2 @dots{} +Return a list as long as the shortest of the argument lists, where +each element is a list. The first list contains the first elements of +the argument lists, the second list contains the second elements, and +so on. +@end deffn + +@deffn procedure unzip1 lst +@deffnx procedure unzip2 lst +@deffnx procedure unzip3 lst +@deffnx procedure unzip4 lst +@deffnx procedure unzip5 lst +@code{unzip1} takes a list of lists, and returns a list containing the +first elements of each list, @code{unzip2} returns two lists, the +first containing the first elements of each lists and the second +containing the second elements of each lists, and so on. +@end deffn + + +@node SRFI-1 Fold and Map +@subsection Fold, Unfold & Map + +@c FIXME::martin: Review me! + +@deffn procedure fold kons knil lst1 lst2 @dots{} +Fold the procedure @var{kons} across all elements of @var{lst1}, +@var{lst2}, @dots{}. Produce the result of + +@code{(@var{kons} @var{en1} @var{en2} @dots{} (@var{kons} @var{e21} +@var{e22} (@var{kons} @var{e11} @var{e12} @var{knil})))}, + +if @var{enm} are the elements of the lists @var{lst1}, @var{lst2}, +@dots{}. +@end deffn + +@deffn procedure fold-right kons knil lst1 lst2 @dots{} +Similar to @code{fold}, but applies @var{kons} in right-to-left order +to the list elements, that is: + +@code{(@var{kons} @var{e11} @var{e12}(@var{kons} @var{e21} +@var{e22} @dots{} (@var{kons} @var{en1} @var{en2} @var{knil})))}, +@end deffn + +@deffn procedure pair-fold kons knil lst1 lst2 @dots{} +Like @code{fold}, but apply @var{kons} to the pairs of the list +instead of the list elements. +@end deffn + +@deffn procedure pair-fold-right kons knil lst1 lst2 @dots{} +Like @code{fold-right}, but apply @var{kons} to the pairs of the list +instead of the list elements. +@end deffn + +@deffn procedure reduce f ridentity lst +@code{reduce} is a variant of @code{reduce}. If @var{lst} is +@code{()}, @var{ridentity} is returned. Otherwise, @code{(fold (car +@var{lst}) (cdr @var{lst}))} is returned. +@end deffn + +@deffn procedure reduce-right f ridentity lst +This is the @code{fold-right} variant of @var{reduce}. +@end deffn + +@deffn procedure unfold p f g seed [tail-gen] +@code{unfold} is defined as follows: + +@lisp +(unfold p f g seed) = + (if (p seed) (tail-gen seed) + (cons (f seed) + (unfold p f g (g seed)))) +@end lisp + +@table @var +@item p +Determines when to stop unfolding. + +@item f +Maps each seed value to the corresponding list element. + +@item g +Maps each seed value to next seed valu. + +@item seed +The state value for the unfold. + +@item tail-gen +Creates the tail of the list; defaults to @code{(lambda (x) '())}. +@end table + +@var{g} produces a series of seed values, which are mapped to list +elements by @var{f}. These elements are put into a list in +left-to-right order, and @var{p} tells when to stop unfolding. +@end deffn + +@deffn procedure unfold-right p f g seed [tail] +Construct a list with the following loop. + +@lisp +(let lp ((seed seed) (lis tail)) + (if (p seed) lis + (lp (g seed) + (cons (f seed) lis)))) +@end lisp + +@table @var +@item p +Determines when to stop unfolding. + +@item f +Maps each seed value to the corresponding list element. + +@item g +Maps each seed value to next seed valu. + +@item seed +The state value for the unfold. + +@item tail-gen +Creates the tail of the list; defaults to @code{(lambda (x) '())}. +@end table + +@end deffn + +@deffn procedure map f lst1 lst2 @dots{} +Map the procedure over the list(s) @var{lst1}, @var{lst2}, @dots{} and +return a list containing the results of the procedure applications. +This procedure is extended with respect to R5RS, because the argument +lists may have different lengths. The result list will have the same +length as the shortest argument lists. The order in which @var{f} +will be applied to the list element(s) is not specified. +@end deffn + +@deffn procedure for-each f lst1 lst2 @dots{} +Apply the procedure @var{f} to each pair of corresponding elements of +the list(s) @var{lst1}, @var{lst2}, @dots{}. The return value is not +specified. This procedure is extended with respect to R5RS, because +the argument lists may have different lengths. The shortest argument +list determines the number of times @var{f} is called. @var{f} will +be applied to tge list elements in left-to-right order. + +@end deffn + +@deffn procedure append-map f lst1 lst2 @dots{} +@deffnx procedure append-map! f lst1 lst2 @dots{} +Equivalent to + +@lisp +(apply append (map f clist1 clist2 ...)) +@end lisp + +and + +@lisp +(apply append! (map f clist1 clist2 ...)) +@end lisp + +Map @var{f} over the elements of the lists, just as in the @code{map} +function. However, the results of the applications are appended +together to make the final result. @code{append-map} uses +@code{append} to append the results together; @code{append-map!} uses +@code{append!}. + +The dynamic order in which the various applications of @var{f} are +made is not specified. +@end deffn + +@deffn procedure map! f lst1 lst2 @dots{} +Linear-update variant of @code{map} -- @code{map!} is allowed, but not +required, to alter the cons cells of @var{lst1} to construct the +result list. + +The dynamic order in which the various applications of @var{f} are +made is not specified. In the n-ary case, @var{lst2}, @var{lst3}, +@dots{} must have at least as many elements as @var{lst1}. +@end deffn + +@deffn procedure pair-for-each f lst1 lst2 @dots{} +Like @code{for-each}, but applies the procedure @var{f} to the pairs +from which the argument lists are constructed, instead of the list +elements. The return value is not specified. +@end deffn + +@deffn procedure filter-map f lst1 lst2 @dots{} +Like @code{map}, but only results from the applications of @var{f} +which are true are saved in the result list. +@end deffn + + +@node SRFI-1 Filtering and Partitioning +@subsection Filtering and Partitioning + +@c FIXME::martin: Review me! + +Filtering means to collect all elements from a list which satisfy a +specific condition. Partitioning a list means to make two groups of +list elements, one which contains the elements satisfying a condition, +and the other for the elements which don't. + +@deffn procedure filter pred lst +@deffnx 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 + +@deffn procedure partition pred lst +@deffnx procedure partition! pred lst +Return two lists, one containing all elements from @var{lst} which +satisfy the predicate @var{pred}, and one list containing the elements +which do not satisfy the predicated. The elements in the result lists +have the same order as in @var{lst}. The order in which @var{pred} is +applied to the list elements is not specified. + +@code{partition!} is allowed, but not required to modify the structure of +the input list. +@end deffn + +@deffn procedure remove pred lst +@deffnx procedure remove! pred lst +Return a list containing all elements from @var{lst} which do not +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{remove!} is allowed, but not required to modify the structure of +the input list. +@end deffn + + +@node SRFI-1 Searching +@subsection Searching + +@c FIXME::martin: Review me! + +The procedures for searching elements in lists either accept a +predicate or a comparison object for determining which elements are to +be searched. + +@deffn procedure find pred lst +Return the first element of @var{lst} which satisfies the predicate +@var{pred} and @code{#f} if no such element is found. +@end deffn + +@deffn procedure find-tail pred lst +Return the first pair of @var{lst} whose @sc{car} satisfies the +predicate @var{pred} and @code{#f} if no such element is found. +@end deffn + +@deffn procedure take-while pred lst +@deffnx procedure take-while! pred lst +Return the longest initial prefix of @var{lst} whose elements all +satisfy the predicate @var{pred}. + +@code{take-while!} is allowed, but not required to modify the input +list while producing the result. +@end deffn + +@deffn procedure drop-while pred lst +Drop the longest initial prefix of @var{lst} whose elements all +satisfy the predicate @var{pred}. +@end deffn + +@deffn procedure span pred lst +@deffnx procedure span! pred lst +@deffnx procedure break pred lst +@deffnx procedure break! pred lst +@code{span} splits the list @var{lst} into the longest initial prefix +whose elements all satisfy the predicate @var{pred}, and the remaining +tail. @code{break} inverts the sense of the predicate. + +@code{span!} and @code{break!} are allowed, but not required to modify +the structure of the input list @var{lst} in order to produce the +result. +@end deffn + +@deffn procedure any pred lst1 lst2 @dots{} +Apply @var{pred} across the lists and return a true value if the +predicate returns true for any of the list elements(s); return +@code{#f} otherwise. The true value returned is always the result of +the first succesful application of @var{pred}. +@end deffn + +@deffn procedure every pred lst1 lst2 @dots{} +Apply @var{pred} across the lists and return a true value if the +predicate returns true for every of the list elements(s); return +@code{#f} otherwise. The true value returned is always the result of +the final succesful application of @var{pred}. +@end deffn + +@deffn procedure list-index pred lst1 lst2 @dots{} +Return the index of the leftmost element that satisfies @var{pred}. +@end deffn + +@deffn procedure member x lst [=] +Return the first sublist of @var{lst} whose @sc{car} is equal to +@var{x}. If @var{x} does no appear in @var{lst}, return @code{#f}. +Equality is determined by the equality predicate @var{=}, or +@code{equal?} if @var{=} is not given. +@end deffn + + +@node SRFI-1 Deleting +@subsection Deleting + +@c FIXME::martin: Review me! + +The procedures for deleting elements from a list either accept a +predicate or a comparison object for determining which elements are to +be removed. + +@deffn procedure delete x lst [=] +@deffnx procedure delete! x lst [=] +Return a list containing all elements from @var{lst}, but without the +elements equal to @var{x}. Equality is determined by the equality +predicate @var{=}, which defaults to @code{equal?} if not given. + +@code{delete!} is allowed, but not required to modify the structure of +the argument list in order to produce the result. +@end deffn + +@deffn procedure delete-duplicates lst [=] +@deffnx procedure delete-duplicates! lst [=] +Return a list containing all elements from @var{lst}, but without +duplicate elements. Equality of elements is determined by the +equality predicate @var{=}, which defaults to @code{equal?} if not +given. + +@code{delete-duplicates!} is allowed, but not required to modify the +structure of the argument list in order to produce the result. +@end deffn + + +@node SRFI-1 Association Lists +@subsection Association Lists + +@c FIXME::martin: Review me! + +Association lists are described in detail in section @ref{Association +Lists}. The present section only documents the additional procedures +for dealing with association lists defined by SRFI-1. + +@deffn procedure assoc key alist [=] +Return the pair from @var{alist} which matches @var{key}. Equality is +determined by @var{=}, which defaults to @code{equal?} if not given. +@var{alist} must be an association lists---a list of pairs. +@end deffn + +@deffn procedure alist-cons key datum alist +Equivalent to + +@lisp +(cons (cons @var{key} @var{datum}) @var{alist}) +@end lisp + +This procedure is used to coons a new pair onto an existing +association list. +@end deffn + +@deffn procedure alist-copy alist +Return a newly allocated copy of @var{alist}, that means that the +spine of the list as well as the pairs are copied. +@end deffn + +@deffn procedure alist-delete key alist [=] +@deffnx procedure alist-delete! key alist [=] +Return a list containing the pairs of @var{alist}, but without the +pairs whose @sc{cars} are equal to @var{key}. Equality is determined +by @var{=}, which defaults to @code{equal?} if not given. + +@code{alist-delete!} is allowed, but not required to modify the +structure of the list @var{alist} in order to produce the result. +@end deffn + + +@node SRFI-1 Set Operations +@subsection Set Operations on Lists + +@c FIXME::martin: Review me! + +Lists can be used for representing sets of objects. The procedures +documented in this section can be used for such set representations. +Man combinding several sets or adding elements, they make sure that no +object is contained more than once in a given list. Please note that +lists are not a too efficient implementation method for sets, so if +you need high performance, you should think about implementing a +custom data structure for representing sets, such as trees, bitsets, +hash tables or something similar. + +All these procedures accept an equality predicate as the first +argument. This predicate is used for testing the objects in the list +sets for sameness. + +@deffn procedure lset<= = list1 @dots{} +Return @code{#t} if every @var{listi} is a subset of @var{listi+1}, +otherwise return @code{#f}. Returns @code{#t} if called with less +than two arguments. @var{=} is used for testing element equality. +@end deffn + +@deffn procedure lset= = list1 list2 @dots{} +Return @code{#t} if all argument lists are equal. @var{=} is used for +testing element equality. +@end deffn + +@deffn procedure lset-adjoin = list elt1 @dots{} +@deffnx procedure lset-adjoin! = list elt1 @dots{} +Add all @var{elts} to the list @var{list}, suppressing duplicates and +return the resulting list. @code{lset-adjoin!} is allowed, but not +required to modify its first argument. @var{=} is used for testing +element equality. +@end deffn + +@deffn procedure lset-union = list1 @dots{} +@deffnx procedure lset-union! = list1 @dots{} +Return the union of all argument list sets. The union is the set of +all elements which appear in any of the argument sets. +@code{lset-union!} is allowed, but not required to modify its first +argument. @var{=} is used for testing element equality. +@end deffn + +@deffn procedure lset-intersection = list1 list2 @dots{} +@deffnx procedure lset-intersection! = list1 list2 @dots{} +Return the intersection of all argument list sets. The intersection +is the set containing all elements which appear in all argument sets. +@code{lset-intersection!} is allowed, but not required to modify its +first argument. @var{=} is used for testing element equality. +@end deffn + +@deffn procedure lset-difference = list1 list2 @dots{} +@deffnx procedure lset-difference! = list1 list2 @dots{} +Return the difference of all argument list sets. The difference is +the the set containing all elements of the first list which do not +appear in the other lists. @code{lset-difference!} is allowed, but +not required to modify its first argument. @var{=} is used for testing +element equality. +@end deffn + +@deffn procedure lset-xor = list1 @dots{} +@deffnx procedure lset-xor! = list1 @dots{} +Return the set containing all elements which appear in the first +argument list set, but not in the second; or, more generally: which +appear in an odd number of sets. @code{lset-xor!} is allowed, but +not required to modify its first argument. @var{=} is used for testing +element equality. +@end deffn + +@deffn procedure lset-diff+intersection = list1 list2 @dots{} +@deffnx procedure lset-diff+intersection! = list1 list2 @dots{} +Return two values, the difference and the intersection of the argument +list sets. This works like a combination of @code{lset-difference} and +@code{lset-intersection}, but is more efficient. +@code{lset-diff+intersection!} is allowed, but not required to modify +its first argument. @var{=} is used for testing element equality. You +have to use some means to deal with the multiple values these +procedures return (@pxref{Multiple Values}). +@end deffn + + +@node SRFI-2 +@section SRFI-2 - and-let* + +@c FIXME::martin: Review me! + +The syntactic form @code{and-let*} combines the conditional evaluation +form @code{and} with the binding form @var{let*}. Each argument +expression will be evaluated sequentially, bound to a variable (if a +variable name is given), but only as long as no expression returns +the false value @code{#f}. + +Use @code{(use-modules (srfi srfi-2)} to access this syntax form. + +A short example will demonstrate how it works. In the first expression, +@var{x} will get bound to 1, but the next expression (@code{#f}) is +false, so evaluation of the form is stopped, and @code{#f} is returned. +In the next expression, @var{x} is bound to 1, @var{y} is bound to +@code{#t} and since no expression in the binding section was false, the +body of the @code{and-let*} expression is evaluated, which in this case +returns the value of @var{x}. + +@lisp +(and-let* ((x 1) (y #f)) 42) +@result{} +#f +(and-let* ((x 1) (y #t)) x) +@result{} +1 +@end lisp + + +@node SRFI-4 +@section SRFI-4 - Homogeneous numeric vector datatypes. + +@c FIXME::martin: Review me! + +SRFI-4 defines a set of datatypes for vectors whose elements are all +of the same numeric type. Vectors for signed and unsigned exact +integer or inexact real numbers in several precisions are available. + +Procedures similar to the vector procedures (@pxref{Vectors}) are +provided for handling these homogeneous vectors, but they are distinct +datatypes. + +The reason for providing this set of datatypes is that with the +limitation (all elements must have the same type), it is possible to +implement them much more memory-efficient than normal, heterogenous +vectors. + +If you want to use these datatypes and the corresponding procedures, +you have to use the module @code{(srfi srfi-4)}. + +Ten vector data types are provided: Unsigned and signed integer values +with 8, 16, 32 and 64 bits and floating point values with 32 and 64 +bits. In the following descriptions, the tags @code{u8}, @code{s8}, +@code{u16}, @code{s16}, @code{u32}, @code{s32}, @code{u64}, +@code{s64}, @code{f32}, @code{f64}, respectively, are used for +denoting the various types. + +@menu +* SRFI-4 - Read Syntax:: How to write homogeneous vector literals. +* SRFI-4 - Procedures:: Available homogeneous vector procedures. +@end menu + + +@node SRFI-4 - Read Syntax +@subsection SRFI-4 - Read Syntax + +Homogeneous numeric vectors have an external representation (read +syntax) similar to normal Scheme vectors, but with an additional tag +telling the vector's type. + +@lisp +#u16(1 2 3) +@end lisp + +denotes a homogeneous numeric vector of three elements, which are the +values 1, 2 and 3, represented as 16-bit unsigned integers. +Correspondingly, + +@lisp +#f64(3.1415 2.71) +@end lisp + +denotes a vector of two elements, which are the values 3.1415 and +2.71, represented as floating-point values of 64 bit precision. + +Please note that the read syntax for floating-point vectors conflicts +with Standard Scheme, because there @code{#f} is defined to be the +literal false value. That means, that with the loaded SRFI-4 module, +it is not possible to enter some list like + +@lisp +'(1 #f3) +@end lisp + +and hope that it will be parsed as a three-element list with the +elements 1, @code{#f} and 3. In normal use, this should be no +problem, because people tend to terminate tokens sensibly when writing +Scheme expressions. + +@node SRFI-4 - Procedures +@subsection SRFI-4 Procedures + +The procedures listed in this section are provided for all homogeneous +numeric vector datatypes. For brevity, they are not all documented, +but a summary of the procedures is given. In the following +descriptions, you can replace @code{TAG} by any of the datatype +indicators @code{u8}, @code{s8}, @code{u16}, @code{s16}, @code{u32}, +@code{s32}, @code{u64}, @code{s64}, @code{f32} and @code{f64}. + +For example, you can use the procedures @code{u8vector?}, +@code{make-s8vector}, @code{u16vector}, @code{u32vector-length}, +@code{s64vector-ref}, @code{f32vector-set!} or @code{f64vector->list}. + +@deffn primitive TAGvector? obj +Return @code{#t} if @var{obj} is a homogeneous numeric vector of type +@code{TAG}. +@end deffn + +@deffn primitive make-TAGvector n [value] +Create a newly allocated homogeneous numeric vector of type +@code{TAG}, which can hold @var{n} elements. If @var{value} is given, +the vector is initialized with the value, otherwise, the contents of +the returned vector is not specified. +@end deffn + +@deffn primitive TAGvector value1 @dots{} +Create a newly allocated homogeneous numeric vector of type +@code{TAG}. The returned vector is as long as the number of arguments +given, and is initialized with the argument values. +@end deffn + +@deffn primitive TAGvector-length TAGvec +Return the number of elements in @var{TAGvec}. +@end deffn + +@deffn primitive TAGvector-ref TAGvec i +Return the element at index @var{i} in @var{TAGvec}. +@end deffn + +@deffn primitive TAGvector-ref TAGvec i value +Set the element at index @var{i} in @var{TAGvec} to @var{value}. The +return value is not specified. +@end deffn + +@deffn primitive TAGvector->list TAGvec +Return a newly allocated list holding all elements of @var{TAGvec}. +@end deffn + +@deffn primitive list->TAGvector lst +Return a newly allocated homogeneous numeric vector of type @code{TAG}, +initialized with the elements of the list @var{lst}. +@end deffn + + +@node SRFI-6 +@section SRFI-6 - Basic String Ports + +SRFI-6 defines the procedures @code{open-input-string}, +@code{open-output-string} and @code{get-output-string}. These +procedures are included in the Guile core, so using this module does not +make any difference at the moment. But it is possible that support for +SRFI-6 will be factored out of the core library in the future, so using +this module does not hurt, after all. + +@node SRFI-8 +@section SRFI-8 - receive + +@code{receive} is a syntax for making the handling of multiple-value +procedures easier. It is documented in @xref{Multiple Values}. + + +@node SRFI-9 +@section SRFI-9 - define-record-type + +This is the SRFI way for defining record types. The Guile +implementation is a layer above Guile's normal record construction +procedures (@pxref{Records}). The nice thing about this kind of record +definition method is that no new names are implicitly created, all +constructor, accessor and predicates are explicitly given. This reduces +the risk of variable capture. + +The syntax of a record type definition is: + +@example +@group +<record type definition> + -> (define-record-type <type name> + (<constructor name> <field tag> ...) + <predicate name> + <field spec> ...) +<field spec> -> (<field tag> <accessor name>) + -> (<field tag> <accessor name> <modifier name>) +<field tag> -> <identifier> +<... name> -> <identifier> +@end group +@end example + +Usage example: + +@example +guile> (use-modules (srfi srfi-9)) +guile> (define-record-type :foo (make-foo x) foo? + (x get-x) (y get-y set-y!)) +guile> (define f (make-foo 1)) +guile> f +#<:foo x: 1 y: #f> +guile> (get-x f) +1 +guile> (set-y! f 2) +2 +guile> (get-y f) +2 +guile> f +#<:foo x: 1 y: 2> +guile> (foo? f) +#t +guile> (foo? 1) +#f +@end example + + +@node SRFI-10 +@section SRFI-10 - Hash-Comma Reader Extension + +@cindex hash-comma +@cindex #,() +The module @code{(srfi srfi-10)} implements the syntax extension +@code{#,()}, also called hash-comma, which is defined in SRFI-10. + +The support for SRFI-10 consists of the procedure +@code{define-reader-ctor} for defining new reader constructors and the +read syntax form + +@example +#,(@var{ctor} @var{datum} ...) +@end example + +where @var{ctor} must be a symbol for which a read constructor was +defined previouly, using @code{define-reader-ctor}. + +Example: + +@lisp +(define-reader-ctor 'file open-input-file) +(define f '#,(file "/etc/passwd")) +(read-line f) +@result{} +"root:x:0:0:root:/root:/bin/bash" +@end lisp + +Please note the quote before the @code{#,(file ...)} expression. This +is necessary because ports are not self-evaluating in Guile. + +@deffn procedure define-reader-ctor symbol proc +Define @var{proc} as the reader constructor for hash-comma forms with a +tag @var{symbol}. @var{proc} will be applied to the datum(s) following +the tag in the hash-comma expression after the complete form has been +read in. The result of @var{proc} is returned by the Scheme reader. +@end deffn + + +@node SRFI-11 +@section SRFI-11 - let-values + +This module implements the binding forms for multiple values +@code{let-values} and @code{let-values*}. These forms are similar to +@code{let} and @code{let*} (@pxref{Local Bindings}), but they support +binding of the values returned by multiple-valued expressions. + +Write @code{(use-modules (srfi srfi-11))} to make the bindings +available. + +@lisp +(let-values (((x y) (values 1 2)) + ((z f) (values 3 4))) + (+ x y z f)) +@result{} +10 +@end lisp + +@code{let-values} performs all bindings simultaneously, which means that +no expression in the binding clauses may refer to variables bound in the +same clause list. @code{let-values*}, on the other hand, performs the +bindings sequentially, just like @code{let*} does for single-valued +expressions. + + +@node SRFI-13 +@section SRFI-13 - String Library + +In this section, we will describe all procedures defined in SRFI-13 +(string library) and implemented by the module @code{(srfi srfi-13)}. + +Note that only the procedures from SRFI-13 are documented here which are +not already contained in Guile. For procedures not documented here +please refer to the relevant chapters in the Guile Reference Manual, for +example the documentation of strings and string procedures +(@pxref{Strings}). + +All of the procedures defined in SRFI-13, which are not already included +in the Guile core library, are implemented in the module @code{(srfi +srfi-13)}. The procedures which are both in Guile and in SRFI-13, but +which are slightly extended, have been implemented in this module, and +the bindings overwrite those in the Guile core. + +The procedures which are defined in the section @emph{Low-level +procedures} of SRFI-13 for parsing optional string indices, substring +specification checking and Knuth-Morris-Pratt-Searching are not +implemented. + +The procedures @code{string-contains} and @code{string-contains-ci} are +not implemented very efficiently at the moment. This will be changed as +soon as possible. + +@menu +* Loading SRFI-13:: How to load SRFI-13 support. +* SRFI-13 Predicates:: String predicates. +* SRFI-13 Constructors:: String constructing procedures. +* SRFI-13 List/String Conversion:: Conversion from/to lists. +* SRFI-13 Selection:: Selection portions of strings. +* SRFI-13 Modification:: Modfify strings in-place. +* SRFI-13 Comparison:: Compare strings. +* SRFI-13 Prefixes/Suffixes:: Detect common pre-/suffixes. +* SRFI-13 Searching:: Searching for substrings. +* SRFI-13 Case Mapping:: Mapping to lower-/upper-case. +* SRFI-13 Reverse/Append:: Reverse and append strings. +* SRFI-13 Fold/Unfold/Map:: Construct/deconstruct strings. +* SRFI-13 Replicate/Rotate:: Replacate and rotate portions of strings. +* SRFI-13 Miscellaneous:: Left-over string procedures. +* SRFI-13 Filtering/Deleting:: Filter and delete characters from strings. +@end menu + + +@node Loading SRFI-13 +@subsection Loading SRFI-13 + +When Guile is properly installed, SRFI-13 support can be loaded into a +running Guile by using the @code{(srfi srfi-13)} module. + +@example +$ guile +guile> (use-modules (srfi srfi-13)) +guile> +@end example + +When this step causes any errors, Guile is not properly installed. + +One possible reason is that Guile cannot find either the Scheme module +file @file{srfi-13.scm}, or it cannot find the shared object file +@file{libguile-srfi-srfi-13-14.so}. Make sure that the former is in the +Guile load path and that the latter is either installed in some default +location like @file{/usr/local/lib} or that the directory it was +installed to is in your @code{LTDL_LIBRARY_PATH}. The same applies to +@file{srfi-14.scm}. + +Now you can test whether the SRFI-13 procedures are working by calling +the @code{string-concatenate} procedure. + +@example +guile> (string-concatenate '("Hello" " " "World!")) +"Hello World!" +@end example + +@node SRFI-13 Predicates +@subsection Predicates + +In addition to the primitives @code{string?} and @code{string-null?}, +which are already in the Guile core, the string predicates +@code{string-any} and @code{string-every} are defined by SRFI-13. + +@deffn primitive string-any pred s [start end] +Check if the predicate @var{pred} is true for any character in +the string @var{s}, proceeding from left (index @var{start}) to +right (index @var{end}). If @code{string-any} returns true, +the returned true value is the one produced by the first +successful application of @var{pred}. +@end deffn + +@deffn primitive string-every pred s [start end] +Check if the predicate @var{pred} is true for every character +in the string @var{s}, proceeding from left (index @var{start}) +to right (index @var{end}). If @code{string-every} returns +true, the returned true value is the one produced by the final +application of @var{pred} to the last character of @var{s}. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Constructors +@subsection Constructors + +SRFI-13 defines several procedures for constructing new strings. In +addition to @code{make-string} and @code{string} (available in the Guile +core library), the procedure @code{string-tabulate} does exist. + +@deffn primitive string-tabulate proc len +@var{proc} is an integer->char procedure. Construct a string +of size @var{len} by applying @var{proc} to each index to +produce the corresponding string element. The order in which +@var{proc} is applied to the indices is not specified. +@end deffn + + +@c =================================================================== + +@node SRFI-13 List/String Conversion +@subsection List/String Conversion + +The procedure @code{string->list} is extended by SRFI-13, that is why it +is included in @code{(srfi srfi-13)}. The other procedures are new. +The Guile core already contains the procedure @code{list->string} for +converting a list of characters into a string (@pxref{List/String +Conversion}). + +@deffn primitive string->list str [start end] +Convert the string @var{str} into a list of characters. +@end deffn + +@deffn primitive reverse-list->string chrs +An efficient implementation of @code{(compose string->list +reverse)}: + +@smalllisp +(reverse-list->string '(#\a #\B #\c)) @result{} "cBa" +@end smalllisp +@end deffn + +@deffn primitive string-join ls [delimiter grammar] +Append the string in the string list @var{ls}, using the string +@var{delim} as a delimiter between the elements of @var{ls}. +@var{grammar} is a symbol which specifies how the delimiter is +placed between the strings, and defaults to the symbol +@code{infix}. + +@table @code +@item infix +Insert the separator between list elements. An empty string +will produce an empty list. + +@item string-infix +Like @code{infix}, but will raise an error if given the empty +list. + +@item suffix +Insert the separator after every list element. + +@item prefix +Insert the separator before each list element. +@end table +@end deffn + + +@c =================================================================== + +@node SRFI-13 Selection +@subsection Selection + +These procedures are called @dfn{selectors}, because they access +information about the string or select pieces of a given string. + +Additional selector procedures are documented in the Strings section +(@pxref{String Selection}), like @code{string-length} or +@code{string-ref}. + +@code{string-copy} is also available in core Guile, but this version +accepts additional start/end indices. + +@deffn primitive string-copy str [start end] +Return a freshly allocated copy of the string @var{str}. If +given, @var{start} and @var{end} delimit the portion of +@var{str} which is copied. +@end deffn + +@deffn primitive substring/shared str start [end] +Like @code{substring}, but the result may share memory with the +argument @var{str}. +@end deffn + +@deffn primitive string-copy! target tstart s [start end] +Copy the sequence of characters from index range [@var{start}, +@var{end}) in string @var{s} to string @var{target}, beginning +at index @var{tstart}. The characters are copied left-to-right +or right-to-left as needed - the copy is guaranteed to work, +even if @var{target} and @var{s} are the same string. It is an +error if the copy operation runs off the end of the target +string. +@end deffn + +@deffn primitive string-take s n +@deffnx primitive string-take-right s n +Return the @var{n} first/last characters of @var{s}. +@end deffn + +@deffn primitive string-drop s n +@deffnx primitive string-drop-right s n +Return all but the first/last @var{n} characters of @var{s}. +@end deffn + +@deffn primitive string-pad s len [chr start end] +@deffnx primitive string-pad-right s len [chr start end] +Take that characters from @var{start} to @var{end} from the +string @var{s} and return a new string, right(left)-padded by the +character @var{chr} to length @var{len}. If the resulting +string is longer than @var{len}, it is truncated on the right (left). +@end deffn + +@deffn primitive string-trim s [char_pred start end] +@deffnx primitive string-trim-right s [char_pred start end] +@deffnx primitive string-trim-both s [char_pred start end] +Trim @var{s} by skipping over all characters on the left/right/both +sides of the string that satisfy the parameter @var{char_pred}: + +@itemize @bullet +@item +if it is the character @var{ch}, characters equal to +@var{ch} are trimmed, + +@item +if it is a procedure @var{pred} characters that +satisfy @var{pred} are trimmed, + +@item +if it is a character set, characters in that set are trimmed. +@end itemize + +If called without a @var{char_pred} argument, all whitespace is +trimmed. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Modification +@subsection Modification + +The procedure @code{string-fill!} is extended from R5RS because it +accepts optional start/end indices. This bindings shadows the procedure +of the same name in the Guile core. The second modification procedure +@code{string-set!} is documented in the Strings section (@pxref{String +Modification}). + +@deffn primitive string-fill! str chr [start end] +Stores @var{chr} in every element of the given @var{str} and +returns an unspecified value. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Comparison +@subsection Comparison + +The procedures in this section are used for comparing strings in +different ways. The comparison predicates differ from those in R5RS in +that they do not only return @code{#t} or @code{#f}, but the mismatch +index in the case of a true return value. + +@code{string-hash} and @code{string-hash-ci} are for calculating hash +values for strings, useful for implementing fast lookup mechanisms. + +@deffn primitive string-compare s1 s2 proc_lt proc_eq proc_gt [start1 end1 start2 end2] +@deffnx primitive string-compare-ci s1 s2 proc_lt proc_eq proc_gt [start1 end1 start2 end2] +Apply @var{proc_lt}, @var{proc_eq}, @var{proc_gt} to the +mismatch index, depending upon whether @var{s1} is less than, +equal to, or greater than @var{s2}. The mismatch index is the +largest index @var{i} such that for every 0 <= @var{j} < +@var{i}, @var{s1}[@var{j}] = @var{s2}[@var{j}] - that is, +@var{i} is the first position that does not match. The +character comparison is done case-insensitively. +@end deffn + +@deffn primitive string= s1 s2 [start1 end1 start2 end2] +@deffnx primitive string<> s1 s2 [start1 end1 start2 end2] +@deffnx primitive string< s1 s2 [start1 end1 start2 end2] +@deffnx primitive string> s1 s2 [start1 end1 start2 end2] +@deffnx primitive string<= s1 s2 [start1 end1 start2 end2] +@deffnx primitive string>= s1 s2 [start1 end1 start2 end2] +Compare @var{s1} and @var{s2} and return @code{#f} if the predicate +fails. Otherwise, the mismatch index is returned (or @var{end1} in the +case of @code{string=}. +@end deffn + +@deffn primitive string-ci= s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-ci<> s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-ci< s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-ci> s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-ci<= s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-ci>= s1 s2 [start1 end1 start2 end2] +Compare @var{s1} and @var{s2} and return @code{#f} if the predicate +fails. Otherwise, the mismatch index is returned (or @var{end1} in the +case of @code{string=}. These are the case-insensitive variants. +@end deffn + +@deffn primitive string-hash s [bound start end] +@deffnx primitive string-hash-ci s [bound start end] +Return a hash value of the string @var{s} in the range 0 @dots{} +@var{bound} - 1. @code{string-hash-ci} is the case-insensitive variant. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Prefixes/Suffixes +@subsection Prefixes/Suffixes + +Using these procedures you can determine whether a given string is a +prefix or suffix of another string or how long a common prefix/suffix +is. + +@deffn primitive string-prefix-length s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-prefix-length-ci s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-suffix-length s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-suffix-length-ci s1 s2 [start1 end1 start2 end2] +Return the length of the longest common prefix/suffix of the two +strings. @code{string-prefix-length-ci} and +@code{string-suffix-length-ci} are the case-insensitive variants. +@end deffn + +@deffn primitive string-prefix? s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-prefix-ci? s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-suffix? s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-suffix-ci? s1 s2 [start1 end1 start2 end2] +Is @var{s1} a prefix/suffix of @var{s2}. @code{string-prefix-ci?} and +@code{string-suffix-ci?} are the case-insensitive variants. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Searching +@subsection Searching + +Use these procedures to find out whether a string contains a given +character or a given substring, or a character from a set of characters. + +@deffn primitive string-index s char_pred [start end] +@deffnx primitive string-index-right s char_pred [start end] +Search through the string @var{s} from left to right (right to left), +returning the index of the first (last) occurence of a character which + +@itemize @bullet +@item +equals @var{char_pred}, if it is character, + +@item +satisifies the predicate @var{char_pred}, if it is a +procedure, + +@item +is in the set @var{char_pred}, if it is a character set. +@end itemize +@end deffn + +@deffn primitive string-skip s char_pred [start end] +@deffnx primitive string-skip-right s char_pred [start end] +Search through the string @var{s} from left to right (right to left), +returning the index of the first (last) occurence of a character which + +@itemize @bullet +@item +does not equal @var{char_pred}, if it is character, + +@item +does not satisify the predicate @var{char_pred}, if it is +a procedure. + +@item +is not in the set if @var{char_pred} is a character set. +@end itemize +@end deffn + +@deffn primitive string-count s char_pred [start end] +Return the count of the number of characters in the string +@var{s} which + +@itemize @bullet +@item +equals @var{char_pred}, if it is character, + +@item +satisifies the predicate @var{char_pred}, if it is a procedure. + +@item +is in the set @var{char_pred}, if it is a character set. +@end itemize +@end deffn + +@deffn primitive string-contains s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-contains-ci s1 s2 [start1 end1 start2 end2] +Does string @var{s1} contain string @var{s2}? Return the index +in @var{s1} where @var{s2} occurs as a substring, or false. +The optional start/end indices restrict the operation to the +indicated substrings. + +@code{string-contains-ci} is the case-insensitive variant. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Case Mapping +@subsection Alphabetic Case Mapping + +These procedures convert the alphabetic case of strings. They are +similar to the procedures in the Guile core, but are extended to handle +optional start/end indices. + +@deffn primitive string-upcase s [start end] +@deffnx primitive string-upcase! s [start end] +Upcase every character in @var{s}. @code{string-upcase!} is the +side-effecting variant. +@end deffn + +@deffn primitive string-downcase s [start end] +@deffnx primitive string-downcase! s [start end] +Downcase every character in @var{s}. @code{string-downcase!} is the +side-effecting variant. +@end deffn + +@deffn primitive string-titlecase s [start end] +@deffnx primitive string-titlecase! s [start end] +Upcase every first character in every word in @var{s}, downcase the +other characters. @code{string-titlecase!} is the side-effecting +variant. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Reverse/Append +@subsection Reverse/Append + +One appending procedure, @code{string-append} is the same in R5RS and in +SRFI-13, so it is not redefined. + +@deffn primitive string-reverse str [start end] +@deffnx primitive string-reverse! str [start end] +Reverse the string @var{str}. The optional arguments +@var{start} and @var{end} delimit the region of @var{str} to +operate on. + +@code{string-reverse!} modifies the argument string and returns an +unspecified value. +@end deffn + +@deffn primitive string-append/shared ls @dots{} +Like @code{string-append}, but the result may share memory +with the argument strings. +@end deffn + +@deffn primitive string-concatenate ls +Append the elements of @var{ls} (which must be strings) +together into a single string. Guaranteed to return a freshly +allocated string. +@end deffn + +@deffn primitive string-concatenate/shared ls +Like @code{string-concatenate}, but the result may share memory +with the strings in the list @var{ls}. +@end deffn + +@deffn primitive string-concatenate-reverse ls final_string end +Without optional arguments, this procedure is equivalent to + +@smalllisp +(string-concatenate (reverse ls)) +@end smalllisp + +If the optional argument @var{final_string} is specified, it is +consed onto the beginning to @var{ls} before performing the +list-reverse and string-concatenate operations. If @var{end} +is given, only the characters of @var{final_string} up to index +@var{end} are used. + +Guaranteed to return a freshly allocated string. +@end deffn + +@deffn primitive string-concatenate-reverse/shared ls final_string end +Like @code{string-concatenate-reverse}, but the result may +share memory with the the strings in the @var{ls} arguments. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Fold/Unfold/Map +@subsection Fold/Unfold/Map + +@code{string-map}, @code{string-for-each} etc. are for iterating over +the characters a string is composed of. The fold and unfold procedures +are list iterators and constructors. + +@deffn primitive string-map proc s [start end] +@var{proc} is a char->char procedure, it is mapped over +@var{s}. The order in which the procedure is applied to the +string elements is not specified. +@end deffn + +@deffn primitive string-map! proc s [start end] +@var{proc} is a char->char procedure, it is mapped over +@var{s}. The order in which the procedure is applied to the +string elements is not specified. The string @var{s} is +modified in-place, the return value is not specified. +@end deffn + +@deffn primitive string-fold kons knil s [start end] +@deffnx primitive string-fold-right kons knil s [start end] +Fold @var{kons} over the characters of @var{s}, with @var{knil} as the +terminating element, from left to right (or right to left, for +@code{string-fold-right}). @var{kons} must expect two arguments: The +actual character and the last result of @var{kons}' application. +@end deffn + +@deffn primitive string-unfold p f g seed [base make_final] +@deffnx primitive string-unfold-right p f g seed [base make_final] +These are the fundamental string constructors. +@itemize @bullet +@item @var{g} is used to generate a series of @emph{seed} +values from the initial @var{seed}: @var{seed}, (@var{g} +@var{seed}), (@var{g}^2 @var{seed}), (@var{g}^3 @var{seed}), +@dots{} +@item @var{p} tells us when to stop - when it returns true +when applied to one of these seed values. +@item @var{f} maps each seed value to the corresponding +character in the result string. These chars are assembled into the +string in a left-to-right (right-to-left) order. +@item @var{base} is the optional initial/leftmost (rightmost) + portion of the constructed string; it default to the empty string. +@item @var{make_final} is applied to the terminal seed +value (on which @var{p} returns true) to produce the final/rightmost +(leftmost) portion of the constructed string. It defaults to +@code{(lambda (x) "")}. +@end itemize +@end deffn + +@deffn primitive string-for-each proc s [start end] +@var{proc} is mapped over @var{s} in left-to-right order. The +return value is not specified. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Replicate/Rotate +@subsection Replicate/Rotate + +These procedures are special substring procedures, which can also be +used for replicating strings. They are a bit tricky to use, but +consider this code fragment, which replicates the input string +@code{"foo"} so often that the resulting string has a length of six. + +@lisp +(xsubstring "foo" 0 6) +@result{} +"foofoo" +@end lisp + +@deffn primitive xsubstring s from [to start end] +This is the @emph{extended substring} procedure that implements +replicated copying of a substring of some string. + +@var{s} is a string, @var{start} and @var{end} are optional +arguments that demarcate a substring of @var{s}, defaulting to +0 and the length of @var{s}. Replicate this substring up and +down index space, in both the positive and negative directions. +@code{xsubstring} returns the substring of this string +beginning at index @var{from}, and ending at @var{to}, which +defaults to @var{from} + (@var{end} - @var{start}). +@end deffn + +@deffn primitive string-xcopy! target tstart s sfrom [sto start end] +Exactly the same as @code{xsubstring}, but the extracted text +is written into the string @var{target} starting at index +@var{tstart}. The operation is not defined if @code{(eq? +@var{target} @var{s})} or these arguments share storage - you +cannot copy a string on top of itself. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Miscellaneous +@subsection Miscellaneous + +@code{string-replace} is for replacing a portion of a string with +another string and @code{string-tokenize} splits a string into a list of +strings, breaking it up at a specified character. + +@deffn primitive string-replace s1 s2 [start1 end1 start2 end2] +Return the string @var{s1}, but with the characters +@var{start1} @dots{} @var{end1} replaced by the characters +@var{start2} @dots{} @var{end2} from @var{s2}. +@end deffn + +@deffn primitive string-tokenize s [token_char start end] +Split the string @var{s} into a list of substrings, where each +substring is a maximal non-empty contiguous sequence of +characters equal to the character @var{token_char}, or +whitespace, if @var{token_char} is not given. If +@var{token_char} is a character set, it is used for finding the +token borders. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Filtering/Deleting +@subsection Filtering/Deleting + +@dfn{Filtering} means to remove all characters from a string which do +not match a given criteria, @dfn{deleting} means the opposite. + +@deffn primitive string-filter s char_pred [start end] +Filter the string @var{s}, retaining only those characters that +satisfy the @var{char_pred} argument. If the argument is a +procedure, it is applied to each character as a predicate, if +it is a character, it is tested for equality and if it is a +character set, it is tested for membership. +@end deffn + +@deffn primitive string-delete s char_pred [start end] +Filter the string @var{s}, retaining only those characters that +do not satisfy the @var{char_pred} argument. If the argument +is a procedure, it is applied to each character as a predicate, +if it is a character, it is tested for equality and if it is a +character set, it is tested for membership. +@end deffn + + +@node SRFI-14 +@section SRFI-14 - Character-set Library + +SRFI-14 defines the data type @dfn{character set}, and also defines a +lot of procedures for handling this character type, and a few standard +character sets like whitespace, alphabetic characters and others. + +All procedures from SRFI-14 (character-set library) are implemented in +the module @code{(srfi srfi-14)}, as well as the standard variables +@code{char-set:letter}, @code{char-set:digit} etc. + +@menu +* Loading SRFI-14:: How to make charsets available. +* SRFI-14 Character Set Data Type:: Underlying data type for charsets. +* SRFI-14 Predicates/Comparison:: Charset predicates. +* SRFI-14 Iterating Over Character Sets:: Enumerate charset elements. +* SRFI-14 Creating Character Sets:: Makeing new charsets. +* SRFI-14 Querying Character Sets:: Test charsets for membership etc. +* SRFI-14 Character-Set Algebra:: Calculating new charsets. +* SRFI-14 Standard Character Sets:: Variables containing predefined charsets. +@end menu + + +@node Loading SRFI-14 +@subsection Loading SRFI-14 + +When Guile is properly installed, SRFI-14 support can be loaded into a +running Guile by using the @code{(srfi srfi-14)} module. + +@example +$ guile +guile> (use-modules (srfi srfi-14)) +guile> (char-set-union (char-set #\f #\o #\o) (string->char-set "bar")) +#<charset @{#\a #\b #\f #\o #\r@}> +guile> +@end example + + +@node SRFI-14 Character Set Data Type +@subsection Character Set Data Type + +The data type @dfn{charset} implements sets of characters +(@pxref{Characters}). Because the internal representation of character +sets is not visible to the user, a lot of procedures for handling them +are provided. + +Character sets can be created, extended, tested for the membership of a +characters and be compared to other character sets. + +The Guile implementation of character sets deals with 8-bit characters. +In the standard variables, only the ASCII part of the character range is +really used, so that for example @dfn{Umlaute} and other accented +characters are not considered to be letters. In the future, as Guile +may get support for international character sets, this will change, so +don't rely on these ``features''. + + +@c =================================================================== + +@node SRFI-14 Predicates/Comparison +@subsection Predicates/Comparison + +Use these procedures for testing whether an object is a character set, +or whether several character sets are equal or subsets of each other. +@code{char-set-hash} can be used for calculating a hash value, maybe for +usage in fast lookup procedures. + +@deffn primitive char-set? obj +Return @code{#t} if @var{obj} is a character set, @code{#f} +otherwise. +@end deffn + +@deffn primitive char-set= cs1 @dots{} +Return @code{#t} if all given character sets are equal. +@end deffn + +@deffn primitive char-set<= cs1 @dots{} +Return @code{#t} if every character set @var{cs}i is a subset +of character set @var{cs}i+1. +@end deffn + +@deffn primitive char-set-hash cs [bound] +Compute a hash value for the character set @var{cs}. If +@var{bound} is given and not @code{#f}, it restricts the +returned value to the range 0 @dots{} @var{bound - 1}. +@end deffn + + +@c =================================================================== + +@node SRFI-14 Iterating Over Character Sets +@subsection Iterating Over Character Sets + +Character set cursors are a means for iterating over the members of a +character sets. After creating a character set cursor with +@code{char-set-cursor}, a cursor can be dereferenced with +@code{char-set-ref}, advanced to the next member with +@code{char-set-cursor-next}. Whether a cursor has passed past the last +element of the set can be checked with @code{end-of-char-set?}. + +Additionally, mapping and (un-)folding procedures for character sets are +provided. + +@deffn primitive char-set-cursor cs +Return a cursor into the character set @var{cs}. +@end deffn + +@deffn primitive char-set-ref cs cursor +Return the character at the current cursor position +@var{cursor} in the character set @var{cs}. It is an error to +pass a cursor for which @code{end-of-char-set?} returns true. +@end deffn + +@deffn primitive char-set-cursor-next cs cursor +Advance the character set cursor @var{cursor} to the next +character in the character set @var{cs}. It is an error if the +cursor given satisfies @code{end-of-char-set?}. +@end deffn + +@deffn primitive end-of-char-set? cursor +Return @code{#t} if @var{cursor} has reached the end of a +character set, @code{#f} otherwise. +@end deffn + +@deffn primitive char-set-fold kons knil cs +Fold the procedure @var{kons} over the character set @var{cs}, +initializing it with @var{knil}. +@end deffn + +@deffn primitive char-set-unfold p f g seed [base_cs] +@deffnx primitive char-set-unfold! p f g seed base_cs +This is a fundamental constructor for character sets. +@itemize @bullet +@item @var{g} is used to generate a series of ``seed'' values +from the initial seed: @var{seed}, (@var{g} @var{seed}), +(@var{g}^2 @var{seed}), (@var{g}^3 @var{seed}), @dots{} +@item @var{p} tells us when to stop -- when it returns true +when applied to one of the seed values. +@item @var{f} maps each seed value to a character. These +characters are added to the base character set @var{base_cs} to +form the result; @var{base_cs} defaults to the empty set. +@end itemize + +@code{char-set-unfold!} is the side-effecting variant. +@end deffn + +@deffn primitive char-set-for-each proc cs +Apply @var{proc} to every character in the character set +@var{cs}. The return value is not specified. +@end deffn + +@deffn primitive char-set-map proc cs +Map the procedure @var{proc} over every character in @var{cs}. +@var{proc} must be a character -> character procedure. +@end deffn + + +@c =================================================================== + +@node SRFI-14 Creating Character Sets +@subsection Creating Character Sets + +New character sets are produced with these procedures. + +@deffn primitive char-set-copy cs +Return a newly allocated character set containing all +characters in @var{cs}. +@end deffn + +@deffn primitive char-set char1 @dots{} +Return a character set containing all given characters. +@end deffn + +@deffn primitive list->char-set char_list [base_cs] +@deffnx primitive list->char-set! char_list base_cs +Convert the character list @var{list} to a character set. If +the character set @var{base_cs} is given, the character in this +set are also included in the result. + +@code{list->char-set!} is the side-effecting variant. +@end deffn + +@deffn primitive string->char-set s [base_cs] +@deffnx primitive string->char-set! s base_cs +Convert the string @var{str} to a character set. If the +character set @var{base_cs} is given, the characters in this +set are also included in the result. + +@code{string->char-set!} is the side-effecting variant. +@end deffn + +@deffn primitive char-set-filter pred cs [base_cs] +@deffnx primitive char-set-filter! pred cs base_cs +Return a character set containing every character from @var{cs} +so that it satisfies @var{pred}. If provided, the characters +from @var{base_cs} are added to the result. + +@code{char-set-filter!} is the side-effecting variant. +@end deffn + +@deffn primitive ucs-range->char-set lower upper [error? base_cs] +@deffnx primitive uce-range->char-set! lower upper error? base_cs +Return a character set containing all characters whose +character codes lie in the half-open range +[@var{lower},@var{upper}). + +If @var{error} is a true value, an error is signalled if the +specified range contains characters which are not contained in +the implemented character range. If @var{error} is @code{#f}, +these characters are silently left out of the resultung +character set. + +The characters in @var{base_cs} are added to the result, if +given. + +@code{ucs-range->char-set!} is the side-effecting variant. +@end deffn + +@deffn procedure ->char-set x +Coerce @var{x} into a character set. @var{x} may be a string, a +character or a character set. +@end deffn + + +@c =================================================================== + +@node SRFI-14 Querying Character Sets +@subsection Querying Character Sets + +Access the elements and other information of a character set with these +procedures. + +@deffn primitive char-set-size cs +Return the number of elements in character set @var{cs}. +@end deffn + +@deffn primitive char-set-count pred cs +Return the number of the elements int the character set +@var{cs} which satisfy the predicate @var{pred}. +@end deffn + +@deffn primitive char-set->list cs +Return a list containing the elements of the character set +@var{cs}. +@end deffn + +@deffn primitive char-set->string cs +Return a string containing the elements of the character set +@var{cs}. The order in which the characters are placed in the +string is not defined. +@end deffn + +@deffn primitive char-set-contains? cs char +Return @code{#t} iff the character @var{ch} is contained in the +character set @var{cs}. +@end deffn + +@deffn primitive char-set-every pred cs +Return a true value if every character in the character set +@var{cs} satisfies the predicate @var{pred}. +@end deffn + +@deffn primitive char-set-any pred cs +Return a true value if any character in the character set +@var{cs} satisfies the predicate @var{pred}. +@end deffn + + +@c =================================================================== + +@node SRFI-14 Character-Set Algebra +@subsection Character-Set Algebra + +Character sets can be manipulated with the common set algebra operation, +such as union, complement, intersection etc. All of these procedures +provide side-effecting variants, which modify their character set +argument(s). + +@deffn primitive char-set-adjoin cs char1 @dots{} +@deffnx primitive char-set-adjoin! cs char1 @dots{} +Add all character arguments to the first argument, which must +be a character set. +@end deffn + +@deffn primitive char-set-delete cs char1 @dots{} +@deffnx primitive char-set-delete! cs char1 @dots{} +Delete all character arguments from the first argument, which +must be a character set. +@end deffn + +@deffn primitive char-set-complement cs +@deffnx primitive char-set-complement! cs +Return the complement of the character set @var{cs}. +@end deffn + +@deffn primitive char-set-union cs1 @dots{} +@deffnx primitive char-set-union! cs1 @dots{} +Return the union of all argument character sets. +@end deffn + +@deffn primitive char-set-intersection cs1 @dots{} +@deffnx primitive char-set-intersection! cs1 @dots{} +Return the intersection of all argument character sets. +@end deffn + +@deffn primitive char-set-difference cs1 @dots{} +@deffnx primitive char-set-difference! cs1 @dots{} +Return the difference of all argument character sets. +@end deffn + +@deffn primitive char-set-xor cs1 @dots{} +@deffnx primitive char-set-xor! cs1 @dots{} +Return the exclusive-or of all argument character sets. +@end deffn + +@deffn primitive char-set-diff+intersection cs1 @dots{} +@deffnx primitive char-set-diff+intersection! cs1 @dots{} +Return the difference and the intersection of all argument +character sets. +@end deffn + + +@c =================================================================== + +@node SRFI-14 Standard Character Sets +@subsection Standard Character Sets + +In order to make the use of the character set data type and procedures +useful, several predefined character set variables exist. + +@defvar char-set:lower-case +All lower-case characters. +@end defvar + +@defvar char-set:upper-case +All upper-case characters. +@end defvar + +@defvar char-set:title-case +This is empty, because ASCII has no titlecase characters. +@end defvar + +@defvar char-set:letter +All letters, e.g. the union of @code{char-set:lower-case} and +@code{char-set:upper-case}. +@end defvar + +@defvar char-set:digit +All digits. +@end defvar + +@defvar char-set:letter+digit +The union of @code{char-set:letter} and @code{char-set:digit}. +@end defvar + +@defvar char-set:graphic +All characters which would put ink on the paper. +@end defvar + +@defvar char-set:printing +The union of @code{char-set:graphic} and @code{char-set:whitespace}. +@end defvar + +@defvar char-set:whitespace +All whitespace characters. +@end defvar + +@defvar char-set:blank +All horizontal whitespace characters, that is @code{#\space} and +@code{#\tab}. +@end defvar + +@defvar char-set:iso-control +The ISO control characters with the codes 0--31 and 127. +@end defvar + +@defvar char-set:punctuation +The characters @code{!"#%&'()*,-./:;?@@[\\]_@{@}} +@end defvar + +@defvar char-set:symbol +The characters @code{$+<=>^`|~}. +@end defvar + +@defvar char-set:hex-digit +The hexadecimal digits @code{0123456789abcdefABCDEF}. +@end defvar + +@defvar char-set:ascii +All ASCII characters. +@end defvar + +@defvar char-set:empty +The empty character set. +@end defvar + +@defvar char-set:full +This character set contains all possible characters. +@end defvar + +@node SRFI-16 +@section SRFI-16 - case-lambda + +@c FIXME::martin: Review me! + +The syntactic form @code{case-lambda} creates procedures, just like +@code{lambda}, but has syntactic extensions for writing procedures of +varying arity easier. + +The syntax of the @code{case-lambda} form is defined in the following +EBNF grammar. + +@example +@group +<case-lambda> + --> (case-lambda <case-lambda-clause>) +<case-lambda-clause> + --> (<formals> <definition-or-command>*) +<formals> + --> (<identifier>*) + | (<identifier>* . <identifier>) + | <identifier> +@end group +@end example + +The value returned by a @code{case-lambda} form is a procedure which +matches the number of actual arguments against the formals in the +various clauses, in order. @dfn{Formals} means a formal argument list +just like with @code{lambda} (@pxref{Lambda}). The first matching clause +is selected, the corresponding values from the actual parameter list are +bound to the variable names in the clauses and the body of the clause is +evaluated. If no clause matches, an error is signalled. + +The following (silly) definition creates a procedure @var{foo} which +acts differently, depending on the number of actual arguments. If one +argument is given, the constant @code{#t} is returned, two arguments are +added and if more arguments are passed, their product is calculated. + +@lisp +(define foo (case-lambda + ((x) #t) + ((x y) (+ x y)) + (z + (apply * z)))) +(foo 'bar) +@result{} +#t +(foo 2 4) +@result{} +6 +(foo 3 3 3) +@result{} +27 +(foo) +@result{} +1 +@end lisp + +The last expression evaluates to 1 because the last clause is matched, +@var{z} is bound to the empty list and the following multiplication, +applied to zero arguments, yields 1. + + +@node SRFI-17 +@section SRFI-17 - Generalized set! + +This is an implementation of SRFI-17: Generalized set! + +It exports the Guile procedure @code{make-procedure-with-setter} under +the SRFI name @code{getter-with-setter} and exports the standard +procedures @code{car}, @code{cdr}, @dots{}, @code{cdddr}, +@code{string-ref} and @code{vector-ref} as procedures with setters, as +required by the SRFI. + +SRFI-17 was heavily criticized during its discussion period but it was +finalized anyway. One issue was its concept of globally associating +setter @dfn{properties} with (procedure) values, which is non-Schemy. +For this reason, this implementation chooses not to provide a way to set +the setter of a procedure. In fact, @code{(set! (setter @var{proc}) +@var{setter})} signals an error. The only way to attach a setter to a +procedure is to create a new object (a @dfn{procedure with setter}) via +the @code{getter-with-setter} procedure. This procedure is also +specified in the SRFI. Using it avoids the described problems. + diff --git a/doc/ref/tcltk.texi b/doc/ref/tcltk.texi new file mode 100644 index 000000000..efc38ea9d --- /dev/null +++ b/doc/ref/tcltk.texi @@ -0,0 +1,3 @@ +@page +@node Tcl/Tk Interface +@chapter Tcl/Tk Interface diff --git a/doc/repl-modules.texi b/doc/repl-modules.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/repl-modules.texi +++ /dev/null diff --git a/doc/scheme-binding.texi b/doc/scheme-binding.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-binding.texi +++ /dev/null diff --git a/doc/scheme-control.texi b/doc/scheme-control.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-control.texi +++ /dev/null diff --git a/doc/scheme-data.texi b/doc/scheme-data.texi deleted file mode 100755 index e69de29bb..000000000 --- a/doc/scheme-data.texi +++ /dev/null diff --git a/doc/scheme-debug.texi b/doc/scheme-debug.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-debug.texi +++ /dev/null diff --git a/doc/scheme-evaluation.texi b/doc/scheme-evaluation.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-evaluation.texi +++ /dev/null diff --git a/doc/scheme-ideas.texi b/doc/scheme-ideas.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-ideas.texi +++ /dev/null diff --git a/doc/scheme-indices.texi b/doc/scheme-indices.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-indices.texi +++ /dev/null diff --git a/doc/scheme-intro.texi b/doc/scheme-intro.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-intro.texi +++ /dev/null diff --git a/doc/scheme-io.texi b/doc/scheme-io.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-io.texi +++ /dev/null diff --git a/doc/scheme-memory.texi b/doc/scheme-memory.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-memory.texi +++ /dev/null diff --git a/doc/scheme-modules.texi b/doc/scheme-modules.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-modules.texi +++ /dev/null diff --git a/doc/scheme-options.texi b/doc/scheme-options.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-options.texi +++ /dev/null diff --git a/doc/scheme-procedures.texi b/doc/scheme-procedures.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-procedures.texi +++ /dev/null diff --git a/doc/scheme-reading.texi b/doc/scheme-reading.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-reading.texi +++ /dev/null diff --git a/doc/scheme-scheduling.texi b/doc/scheme-scheduling.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-scheduling.texi +++ /dev/null diff --git a/doc/scheme-translation.texi b/doc/scheme-translation.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-translation.texi +++ /dev/null diff --git a/doc/scheme-utility.texi b/doc/scheme-utility.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scheme-utility.texi +++ /dev/null diff --git a/doc/scm.texi b/doc/scm.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scm.texi +++ /dev/null diff --git a/doc/script-getopt.texi b/doc/script-getopt.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/script-getopt.texi +++ /dev/null diff --git a/doc/scripts.texi b/doc/scripts.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scripts.texi +++ /dev/null diff --git a/doc/scsh.texi b/doc/scsh.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/scsh.texi +++ /dev/null diff --git a/doc/slib.texi b/doc/slib.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/slib.texi +++ /dev/null diff --git a/doc/env.texi b/doc/sources/env.texi index 712cce310..dc6bf9a40 100644 --- a/doc/env.texi +++ b/doc/sources/env.texi @@ -47,7 +47,7 @@ Copyright @copyright{} 1999 Free Software Foundation, Inc. @chapter Motivation @example -$Id: env.texi,v 1.2 2001-04-22 14:56:52 ossau Exp $ +$Id: env.texi,v 1.1 2001-08-24 09:40:29 ossau Exp $ @end example This is a draft proposal for a new datatype for representing top-level diff --git a/doc/sources/format.texi b/doc/sources/format.texi new file mode 100644 index 000000000..122e0453d --- /dev/null +++ b/doc/sources/format.texi @@ -0,0 +1,434 @@ + +@menu +* Format Interface:: +* Format Specification:: +@end menu + +@node Format Interface, Format Specification, Format, Format +@subsection Format Interface + +@defun format destination format-string . arguments +An almost complete implementation of Common LISP format description +according to the CL reference book @cite{Common LISP} from Guy L. +Steele, Digital Press. Backward compatible to most of the available +Scheme format implementations. + +Returns @code{#t}, @code{#f} or a string; has side effect of printing +according to @var{format-string}. If @var{destination} is @code{#t}, +the output is to the current output port and @code{#t} is returned. If +@var{destination} is @code{#f}, a formatted string is returned as the +result of the call. NEW: If @var{destination} is a string, +@var{destination} is regarded as the format string; @var{format-string} is +then the first argument and the output is returned as a string. If +@var{destination} is a number, the output is to the current error port +if available by the implementation. Otherwise @var{destination} must be +an output port and @code{#t} is returned.@refill + +@var{format-string} must be a string. In case of a formatting error +format returns @code{#f} and prints a message on the current output or +error port. Characters are output as if the string were output by the +@code{display} function with the exception of those prefixed by a tilde +(~). For a detailed description of the @var{format-string} syntax +please consult a Common LISP format reference manual. For a test suite +to verify this format implementation load @file{formatst.scm}. Please +send bug reports to @code{lutzeb@@cs.tu-berlin.de}. + +Note: @code{format} is not reentrant, i.e. only one @code{format}-call +may be executed at a time. + +@end defun + +@node Format Specification, , Format Interface, Format +@subsection Format Specification (Format version 3.0) + +Please consult a Common LISP format reference manual for a detailed +description of the format string syntax. For a demonstration of the +implemented directives see @file{formatst.scm}.@refill + +This implementation supports directive parameters and modifiers +(@code{:} and @code{@@} characters). Multiple parameters must be +separated by a comma (@code{,}). Parameters can be numerical parameters +(positive or negative), character parameters (prefixed by a quote +character (@code{'}), variable parameters (@code{v}), number of rest +arguments parameter (@code{#}), empty and default parameters. Directive +characters are case independent. The general form of a directive +is:@refill + +@noindent +@var{directive} ::= ~@{@var{directive-parameter},@}[:][@@]@var{directive-character} + +@noindent +@var{directive-parameter} ::= [ [-|+]@{0-9@}+ | '@var{character} | v | # ] + + +@subsubsection Implemented CL Format Control Directives + +Documentation syntax: Uppercase characters represent the corresponding +control directive characters. Lowercase characters represent control +directive parameter descriptions. + +@table @asis +@item @code{~A} +Any (print as @code{display} does). +@table @asis +@item @code{~@@A} +left pad. +@item @code{~@var{mincol},@var{colinc},@var{minpad},@var{padchar}A} +full padding. +@end table +@item @code{~S} +S-expression (print as @code{write} does). +@table @asis +@item @code{~@@S} +left pad. +@item @code{~@var{mincol},@var{colinc},@var{minpad},@var{padchar}S} +full padding. +@end table +@item @code{~D} +Decimal. +@table @asis +@item @code{~@@D} +print number sign always. +@item @code{~:D} +print comma separated. +@item @code{~@var{mincol},@var{padchar},@var{commachar}D} +padding. +@end table +@item @code{~X} +Hexadecimal. +@table @asis +@item @code{~@@X} +print number sign always. +@item @code{~:X} +print comma separated. +@item @code{~@var{mincol},@var{padchar},@var{commachar}X} +padding. +@end table +@item @code{~O} +Octal. +@table @asis +@item @code{~@@O} +print number sign always. +@item @code{~:O} +print comma separated. +@item @code{~@var{mincol},@var{padchar},@var{commachar}O} +padding. +@end table +@item @code{~B} +Binary. +@table @asis +@item @code{~@@B} +print number sign always. +@item @code{~:B} +print comma separated. +@item @code{~@var{mincol},@var{padchar},@var{commachar}B} +padding. +@end table +@item @code{~@var{n}R} +Radix @var{n}. +@table @asis +@item @code{~@var{n},@var{mincol},@var{padchar},@var{commachar}R} +padding. +@end table +@item @code{~@@R} +print a number as a Roman numeral. +@item @code{~:@@R} +print a number as an ``old fashioned'' Roman numeral. +@item @code{~:R} +print a number as an ordinal English number. +@item @code{~:@@R} +print a number as a cardinal English number. +@item @code{~P} +Plural. +@table @asis +@item @code{~@@P} +prints @code{y} and @code{ies}. +@item @code{~:P} +as @code{~P but jumps 1 argument backward.} +@item @code{~:@@P} +as @code{~@@P but jumps 1 argument backward.} +@end table +@item @code{~C} +Character. +@table @asis +@item @code{~@@C} +prints a character as the reader can understand it (i.e. @code{#\} prefixing). +@item @code{~:C} +prints a character as emacs does (eg. @code{^C} for ASCII 03). +@end table +@item @code{~F} +Fixed-format floating-point (prints a flonum like @var{mmm.nnn}). +@table @asis +@item @code{~@var{width},@var{digits},@var{scale},@var{overflowchar},@var{padchar}F} +@item @code{~@@F} +If the number is positive a plus sign is printed. +@end table +@item @code{~E} +Exponential floating-point (prints a flonum like @var{mmm.nnn}@code{E}@var{ee}). +@table @asis +@item @code{~@var{width},@var{digits},@var{exponentdigits},@var{scale},@var{overflowchar},@var{padchar},@var{exponentchar}E} +@item @code{~@@E} +If the number is positive a plus sign is printed. +@end table +@item @code{~G} +General floating-point (prints a flonum either fixed or exponential). +@table @asis +@item @code{~@var{width},@var{digits},@var{exponentdigits},@var{scale},@var{overflowchar},@var{padchar},@var{exponentchar}G} +@item @code{~@@G} +If the number is positive a plus sign is printed. +@end table +@item @code{~$} +Dollars floating-point (prints a flonum in fixed with signs separated). +@table @asis +@item @code{~@var{digits},@var{scale},@var{width},@var{padchar}$} +@item @code{~@@$} +If the number is positive a plus sign is printed. +@item @code{~:@@$} +A sign is always printed and appears before the padding. +@item @code{~:$} +The sign appears before the padding. +@end table +@item @code{~%} +Newline. +@table @asis +@item @code{~@var{n}%} +print @var{n} newlines. +@end table +@item @code{~&} +print newline if not at the beginning of the output line. +@table @asis +@item @code{~@var{n}&} +prints @code{~&} and then @var{n-1} newlines. +@end table +@item @code{~|} +Page Separator. +@table @asis +@item @code{~@var{n}|} +print @var{n} page separators. +@end table +@item @code{~~} +Tilde. +@table @asis +@item @code{~@var{n}~} +print @var{n} tildes. +@end table +@item @code{~}<newline> +Continuation Line. +@table @asis +@item @code{~:}<newline> +newline is ignored, white space left. +@item @code{~@@}<newline> +newline is left, white space ignored. +@end table +@item @code{~T} +Tabulation. +@table @asis +@item @code{~@@T} +relative tabulation. +@item @code{~@var{colnum,colinc}T} +full tabulation. +@end table +@item @code{~?} +Indirection (expects indirect arguments as a list). +@table @asis +@item @code{~@@?} +extracts indirect arguments from format arguments. +@end table +@item @code{~(@var{str}~)} +Case conversion (converts by @code{string-downcase}). +@table @asis +@item @code{~:(@var{str}~)} +converts by @code{string-capitalize}. +@item @code{~@@(@var{str}~)} +converts by @code{string-capitalize-first}. +@item @code{~:@@(@var{str}~)} +converts by @code{string-upcase}. +@end table +@item @code{~*} +Argument Jumping (jumps 1 argument forward). +@table @asis +@item @code{~@var{n}*} +jumps @var{n} arguments forward. +@item @code{~:*} +jumps 1 argument backward. +@item @code{~@var{n}:*} +jumps @var{n} arguments backward. +@item @code{~@@*} +jumps to the 0th argument. +@item @code{~@var{n}@@*} +jumps to the @var{n}th argument (beginning from 0) +@end table +@item @code{~[@var{str0}~;@var{str1}~;...~;@var{strn}~]} +Conditional Expression (numerical clause conditional). +@table @asis +@item @code{~@var{n}[} +take argument from @var{n}. +@item @code{~@@[} +true test conditional. +@item @code{~:[} +if-else-then conditional. +@item @code{~;} +clause separator. +@item @code{~:;} +default clause follows. +@end table +@item @code{~@{@var{str}~@}} +Iteration (args come from the next argument (a list)). +@table @asis +@item @code{~@var{n}@{} +at most @var{n} iterations. +@item @code{~:@{} +args from next arg (a list of lists). +@item @code{~@@@{} +args from the rest of arguments. +@item @code{~:@@@{} +args from the rest args (lists). +@end table +@item @code{~^} +Up and out. +@table @asis +@item @code{~@var{n}^} +aborts if @var{n} = 0 +@item @code{~@var{n},@var{m}^} +aborts if @var{n} = @var{m} +@item @code{~@var{n},@var{m},@var{k}^} +aborts if @var{n} <= @var{m} <= @var{k} +@end table +@end table + + +@subsubsection Not Implemented CL Format Control Directives + +@table @asis +@item @code{~:A} +print @code{#f} as an empty list (see below). +@item @code{~:S} +print @code{#f} as an empty list (see below). +@item @code{~<~>} +Justification. +@item @code{~:^} +(sorry I don't understand its semantics completely) +@end table + + +@subsubsection Extended, Replaced and Additional Control Directives + +@table @asis +@item @code{~@var{mincol},@var{padchar},@var{commachar},@var{commawidth}D} +@item @code{~@var{mincol},@var{padchar},@var{commachar},@var{commawidth}X} +@item @code{~@var{mincol},@var{padchar},@var{commachar},@var{commawidth}O} +@item @code{~@var{mincol},@var{padchar},@var{commachar},@var{commawidth}B} +@item @code{~@var{n},@var{mincol},@var{padchar},@var{commachar},@var{commawidth}R} +@var{commawidth} is the number of characters between two comma characters. +@end table + +@table @asis +@item @code{~I} +print an R5RS complex number as @code{~F~@@Fi} with passed parameters for +@code{~F}. +@item @code{~Y} +Pretty print formatting of an argument for scheme code lists. +@item @code{~K} +Same as @code{~?.} +@item @code{~!} +Flushes the output if format @var{destination} is a port. +@item @code{~_} +Print a @code{#\space} character +@table @asis +@item @code{~@var{n}_} +print @var{n} @code{#\space} characters. +@end table +@item @code{~/} +Print a @code{#\tab} character +@table @asis +@item @code{~@var{n}/} +print @var{n} @code{#\tab} characters. +@end table +@item @code{~@var{n}C} +Takes @var{n} as an integer representation for a character. No arguments +are consumed. @var{n} is converted to a character by +@code{integer->char}. @var{n} must be a positive decimal number.@refill +@item @code{~:S} +Print out readproof. Prints out internal objects represented as +@code{#<...>} as strings @code{"#<...>"} so that the format output can always +be processed by @code{read}. +@refill +@item @code{~:A} +Print out readproof. Prints out internal objects represented as +@code{#<...>} as strings @code{"#<...>"} so that the format output can always +be processed by @code{read}. +@item @code{~Q} +Prints information and a copyright notice on the format implementation. +@table @asis +@item @code{~:Q} +prints format version. +@end table +@refill +@item @code{~F, ~E, ~G, ~$} +may also print number strings, i.e. passing a number as a string and +format it accordingly. +@end table + +@subsubsection Configuration Variables + +Format has some configuration variables at the beginning of +@file{format.scm} to suit the systems and users needs. There should be +no modification necessary for the configuration that comes with SLIB. +If modification is desired the variable should be set after the format +code is loaded. Format detects automatically if the running scheme +system implements floating point numbers and complex numbers. + +@table @asis + +@item @var{format:symbol-case-conv} +Symbols are converted by @code{symbol->string} so the case type of the +printed symbols is implementation dependent. +@code{format:symbol-case-conv} is a one arg closure which is either +@code{#f} (no conversion), @code{string-upcase}, @code{string-downcase} +or @code{string-capitalize}. (default @code{#f}) + +@item @var{format:iobj-case-conv} +As @var{format:symbol-case-conv} but applies for the representation of +implementation internal objects. (default @code{#f}) + +@item @var{format:expch} +The character prefixing the exponent value in @code{~E} printing. (default +@code{#\E}) + +@end table + +@subsubsection Compatibility With Other Format Implementations + +@table @asis +@item SLIB format 2.x: +See @file{format.doc}. + +@item SLIB format 1.4: +Downward compatible except for padding support and @code{~A}, @code{~S}, +@code{~P}, @code{~X} uppercase printing. SLIB format 1.4 uses C-style +@code{printf} padding support which is completely replaced by the CL +@code{format} padding style. + +@item MIT C-Scheme 7.1: +Downward compatible except for @code{~}, which is not documented +(ignores all characters inside the format string up to a newline +character). (7.1 implements @code{~a}, @code{~s}, +~@var{newline}, @code{~~}, @code{~%}, numerical and variable +parameters and @code{:/@@} modifiers in the CL sense).@refill + +@item Elk 1.5/2.0: +Downward compatible except for @code{~A} and @code{~S} which print in +uppercase. (Elk implements @code{~a}, @code{~s}, @code{~~}, and +@code{~%} (no directive parameters or modifiers)).@refill + +@item Scheme->C 01nov91: +Downward compatible except for an optional destination parameter: S2C +accepts a format call without a destination which returns a formatted +string. This is equivalent to a #f destination in S2C. (S2C implements +@code{~a}, @code{~s}, @code{~c}, @code{~%}, and @code{~~} (no directive +parameters or modifiers)).@refill + +@end table + +This implementation of format is solely useful in the SLIB context +because it requires other components provided by SLIB.@refill diff --git a/doc/srfi-modules.texi b/doc/srfi-modules.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/srfi-modules.texi +++ /dev/null diff --git a/doc/tcltk.texi b/doc/tcltk.texi deleted file mode 100644 index e69de29bb..000000000 --- a/doc/tcltk.texi +++ /dev/null diff --git a/doc/tutorial/.cvsignore b/doc/tutorial/.cvsignore new file mode 100644 index 000000000..8eaa8267a --- /dev/null +++ b/doc/tutorial/.cvsignore @@ -0,0 +1,23 @@ +Makefile +Makefile.in +stamp-vti +stamp-vti.1 +*.log +*.dvi +*.aux +*.toc +*.cp +*.fn +*.vr +*.tp +*.ky +*.pg +*.cps +*.fns +*.tps +*.vrs +*.ps +*.info* +*.html +version.texi +version-tutorial.texi diff --git a/doc/tutorial/ChangeLog-guile-doc-tutorial b/doc/tutorial/ChangeLog-guile-doc-tutorial new file mode 100644 index 000000000..9d7233a31 --- /dev/null +++ b/doc/tutorial/ChangeLog-guile-doc-tutorial @@ -0,0 +1,16 @@ +2001-01-27 Neil Jerram <neil@ossau.uklinux.net> + + * texinfo.tex: Replaced by latest version from ftp.gnu.org. + +1999-12-06 Gary Houston <ghouston@freewire.co.uk> + + * guile-tut.texi: tweaked the dircategory. + +1998-01-28 Mark Galassi <rosalia@nis.lanl.gov> + + * guile-tut.texi: set @dircategory to "Scheme Programming". + +Mon Aug 18 16:11:43 1997 Jim Blandy <jimb@totoro.red-bean.com> + + * texinfo.tex: Installed from texinfo release 3.11. + diff --git a/doc/tutorial/guile-tut.texi b/doc/tutorial/guile-tut.texi new file mode 100644 index 000000000..b300e2efa --- /dev/null +++ b/doc/tutorial/guile-tut.texi @@ -0,0 +1,1334 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename guile-tut.info +@settitle Guile Tutorial +@set guile-tut + +@include version-tutorial.texi + +@dircategory The Algorithmic Language Scheme +@direntry +* Guile Tutorial: (guile-tut). The Guile tutorial. +@end direntry + +@setchapternewpage off +@c Choices for setchapternewpage are {on,off,odd}. +@paragraphindent 2 +@c %**end of header + +@iftex +@finalout +@c DL: lose the egregious vertical whitespace, esp. around examples +@c but paras in @defun-like things don't have parindent +@parskip 4pt plus 1pt +@end iftex + +@titlepage +@title Guile Tutorial +@subtitle For use with Guile @value{VERSION} +@subtitle Last updated @value{UPDATED} +@include AUTHORS + +@page +@vskip 0pt plus 1filll +Copyright @copyright{} 1997, 1998 Free Software Foundation + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation approved +by the author. +@end titlepage + + +@ifinfo +@node Top +@top Guile Tutorial +@end ifinfo + +@ifinfo +This file gives a tutorial introductionto Guile. + +Copyright (C) 1997 Free Software Foundation + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). + +@end ignore +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation approved +by the author. +@end ifinfo + + +@menu +* Jump Start:: +* Introduction:: +* Using Guile to program in Scheme:: +* Guile in a Library:: +* Regular Expression Support:: +* UNIX System Programming:: +* Where to find more Guile/Scheme resources:: +* Concept Index:: +* Procedure and Macro Index:: +* Variable Index:: +* Type Index:: +@end menu + +@node Jump Start +@chapter Jump Start + +@noindent +Before giving an overview of Guile, I present some simple commands and +programs that you can type to get going immediately. + +Start by invoking the Guile interpreter (usually you do this by just +typing @code{guile}). Then type (or paste) the following expressions at +the prompt; the interpreter's response is preceded (in this manual) by +@result{}. + +@example +<shell-prompt> guile +@end example +@lisp +(+ 20 35) +@result{} 55 +(define (recursive-factorial n) + (if (= n 0) + 1 + (* n (recursive-factorial (- n 1))))) +(recursive-factorial 5) +@result{} 120 +(recursive-factorial 500) +@result{} 1220136825991110068701238785423046926253574342803192842192413588 + 3858453731538819976054964475022032818630136164771482035841633787 + 2207817720048078520515932928547790757193933060377296085908627042 + 9174547882424912726344305670173270769461062802310452644218878789 + 4657547771498634943677810376442740338273653974713864778784954384 + 8959553753799042324106127132698432774571554630997720278101456108 + 1188373709531016356324432987029563896628911658974769572087926928 + 8712817800702651745077684107196243903943225364226052349458501299 + 1857150124870696156814162535905669342381300885624924689156412677 + 5654481886506593847951775360894005745238940335798476363944905313 + 0623237490664450488246650759467358620746379251842004593696929810 + 2226397195259719094521782333175693458150855233282076282002340262 + 6907898342451712006207714640979456116127629145951237229913340169 + 5523638509428855920187274337951730145863575708283557801587354327 + 6888868012039988238470215146760544540766353598417443048012893831 + 3896881639487469658817504506926365338175055478128640000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000 +<control-D> +@end lisp + +In this example we did some simple arithmetic @code{(+ 20 35)} and got +the answer @code{55}. Then we coded the classic (and rather wasteful) +factorial algorithm, and got a glimpse of Scheme's nice +@emph{bignumbers} by asking for the factorial of 1000. Then we quit +with @code{(quit)}. +@cindex bignumbers + +This is the most basic use of Guile: a simple Scheme interpreter. In +the rest of this tutorial I will show you how Guile has many facets: it +is also an @emph{extensible} interpreter (to which many features can be +easilly added) and an @emph{embeddable} interpreter (which can be +invoked from your C programs). + + +@node Introduction +@chapter Introduction + +@noindent +@dfn{Guile} (which can stand for @emph{GNU Ubiquitous Intelligent +Language Extension}) is the GNU extension language. It started out as +an embeddable Scheme interpreter, and has rapidly evolved into a +kitchen-sink package including a standalone Scheme interpreter, an +embeddable Scheme interpreter, several graphics options, other languages +that can be used along with Scheme (for now just @emph{ctax} and +@emph{Tcl}), and hooks for much more. + + +@menu +* What are scripting and extension languages:: +* History of Guile and its motivations:: +* How to characterize Guile:: +@end menu + +@node What are scripting and extension languages +@section What are scripting and extension languages +@cindex scripting languages +@cindex extension languages + +A @dfn{scripting language} is a programming language which serves as +glue between other system programs. In the UNIX world, the traditional +scripting language is the @emph{Bourne shell}, which allows many UNIX +commands to be executed in sequence, or in a pipeline. Traditional UNIX +commands are cleverly written to work well when put together in a +script. + +Other examples of UNIX scripting languages are AWK, Perl, Scsh (the +Scheme Shell: a Scheme interpreter enhanced to do good scripting), +Python, Tcl, Java @dots{} +@cindex scripting languages - examples + +UNIX programmers noticed, more than 25 years ago, that scripting +languages can do serious work, so the Bourne shell was written to have +variables, operators and control structures, just like a full-featured +programming language. +@cindex Bourne shell + +What scripting languages have, that traditional programming languages do +not, is the ability to easily run an external program (or a pipeline of +external programs) and use the returned values and output from that +program in useful ways. + +An @dfn{extension language} is a programming language interpreter +offered by an application program, so that users can write macros or +even full-fledged programs to extend the original application. +Extension languages have a C interface (it is usually C, but it could be +any other compiled language), and can be given access to the C data +structures. Likewise, there are C routines to access the extension +language data structures. + +Extension languages abound in the software world, even though the name +@emph{extension language} is seldom used. Examples are: +@cindex extension languages - examples + +@itemize @bullet +@item +Emacs Lisp, the language used to program and customize GNU Emacs. +@cindex Emacs Lisp + +@item +Tcl, John Ousterhout's general-purpose scripting and extension language. +@cindex Tcl + +@item +The Lotus 1-2-3 macro language (any spreadsheet macro language, +really). I mention this one first because it is a classic, even though +it is seldom used any more. +@cindex Lotus 1-2-3 + +@item +Other spreadsheet and database macro languages. + +@item +The Dominion empire-style game's @emph{exec} files. +@cindex Dominion + +@item +Any syntax for a ".*rc" file you might have used. Almost all programs +end up parsing some kind of startup or configuration file. The syntax +for those can get pretty involved, thus justifying calling them +"extension languages". The @emph{fvwm} window manager, for example, +parses a rather elaborate @file{.fvwmrc} file. + +@item +Brent Benson's libscheme.a, an embeddable Scheme interpreter. +@cindex Benson, Brent +@cindex libscheme + +@item +Guile, the GNU extension language, which is the subject of this +tutorial. + +@end itemize + +One lesson we can learn from looking at classical large software +applications is that "writers of large programs" always end up throwing +in some kind of parser for configuration or scripting. + +Of the examples listed above, Emacs Lisp, Tcl, Libscheme and Guile have +an important property: they are not added as an afterthought for a +specific application. They are general-purpose languages which a user +can learn (even in college courses) and then use to customize the +application program. + +This is a recent and (in my opinion) very exciting direction in +large-program software engineering: program designers can link in the +Guile or Tcl library from the very beginning, and tell their users "You +want to customize this program? Just use Scheme (or Tcl, or whatever +language), which you already know!" +@cindex large programs + + +@node History of Guile and its motivations +@section History of Guile and its motivations + +A few separate threads of events led to the development of Guile. + +In the fall of 1994, Richard Stallman, director of the GNU project, +posted an article with the subject "Why you should not use Tcl", in +which he argued that Tcl is inadequate as an extension language. This +generated a flurry of flames (available in the hypermail archive +(@url{http://www.utdallas.edu/acc/glv/Tcl/war/}) @strong{The Tcl War}). +@cindex Stallman, Richard +@cindex GNU project +@cindex Tcl + +The result was that Stallman then proposed his design for the GNU +Extension Language, first called GEL and then renamed Guile. The +discussion triggered by that article is also available in a hypermail +archive, @url{http://www.utdallas.edu/acc/glv/Tcl/war2/}. + +One interesting feature of this GNU Extension Language plan was that +users should have a @emph{choice} of languages to use in extending their +program. The basic language would be a slightly modified Scheme, and +translators would be written to convert other languages (like Tcl, +Python, Perl, C-like languages @dots{}) into Scheme. + +Tom Lord started working on this project immediately, taking Aubrey +Jaffer's small and portable implementation of Scheme, SCM, and making it +into an embeddable interpreter: callable from C and allowing new Scheme +procedures to be written in C. +@cindex Lord, Tom +@cindex Jaffer, Aubrey + +In the spring of 1995, the guile-ii snapshot was released. This made it +possible to start writing code in C and Scheme using the guile +facilities. + +The guile-iii snapshot was released the summer of 1995, and it had fixed +enough problems so that the access to Scheme data structures from C was +almost complete. + +After this, Cygnus Support added many features to Guile and finished +implementing others, so that Guile acquired thread support, a regular +expression matcher, a Tk interface, an interface to the SGI OpenGL +graphics system, an @emph{applet} formalism, and some other packages. +This was all in the Cygnus Guile r0.3 and r0.4 releases. +@cindex Cygnus Support + +Meanwhile, Tom Lord left the project after having produced a divergent +version of Guile: 1.0b2. The Free Software Foundation hired Jim Blandy +to coordinate Guile development. The FSF released its first version of +Guile in January 1997. In the future, many of the Cygnus packages will +be re-integrated into Guile. +@cindex Blandy, Jim +@cindex Free Software Foundation + + + +@node How to characterize Guile +@section How to characterize Guile + +I have already mentioned that Guile has become a kitchen sink package; +here you can see how Guile freely takes new commands and constructs from +the portable Scheme library @emph{slib}, the @emph{Tk} widget set, a +posix library (useful for UNIX systems programming), the regular +expression library @emph{rx}, and many more @dots{} +@cindex slib +@cindex Tk +@cindex POSIX +@c @cindex OpenGL +@cindex rx + +So Guile has many more primitive procedures available to it than those +specified in @ref{Standard Procedures, Revised(5) Report on the +Algorithmic Language Scheme, , r5rs, Revised(5) Report on the +Algorithmic Language Scheme}. On top of that, Guile will interpret +almost all standard Scheme programs. The only incompatible difference +between the basic Guile language and R5RS Scheme is that Guile is case +sensitive, whereas R5RS is case insensitive. We hope that few people +have written Scheme programs that depend on case insensitivity. +@cindex case sensitivity +@cindex Revised(5) Report on the Algorithmic Language Scheme +@cindex report on Scheme +@cindex Scheme language - report +@cindex Scheme language - definition + +Here is a possible view of the @emph{sum of the parts} in Guile: +@cindex extensions to standard Scheme +@cindex extensions to R5RS +@cindex Scheme extensions +@example +guile = standard Scheme (R5RS) + PLUS extensions to R5RS offered by SCM + PLUS some extra primitives offered by Guile (catch/throw) + PLUS portable Scheme library (SLIB) + PLUS embeddable Scheme interpreter library (libguile) + PLUS Tk toolkit + PLUS threads + PLUS Posix library +@c PLUS OpenGL library (mesa) +@c PLUS OpenGL toolkit (glut) + PLUS Regular expression library (rx) +@c PLUS Applet formalism + PLUS Tcl library +@end example + + +@node Using Guile to program in Scheme +@chapter Using Guile to program in Scheme +@cindex Scheme programming tutorial +@cindex tutorial on Scheme programming + +In this section I give a tutorial introduction to programming in Scheme, +with a slant toward the interesting things that can be done in Guile. + +@c Applets are so @emph{chic} that they get their own section, but this +This section will try to touch on many of the interesting and cool +aspects of Guile, showing you how new types of problems can be solved +with Guile. Note that using Guile as a library with @code{libguile.a} +is described in its own chapter (@pxref{Guile in a Library}). Also note +that some small examples are given in @ref{Jump Start}. + +To get started you need to know how to program in @dfn{Scheme} (a +dialect of LISP). Fortunately Scheme is a small, clean language and is +not hard to learn. It is also used in many undergraduate courses to +introduce computer programming. +@cindex lisp dialects + +I will not try to teach you Scheme here (although you might end up +learning by example), since there are many good books on the subject, +listed in @ref{Where to find more Guile/Scheme resources}. @footnote{To +get started, look at the books @cite{Simply Scheme} and @cite{The Little +Schemer} from that list.} + + +@subsection Hello World +@cindex hello world + +Our first program is the typical Scheme "hello world" program. Put the +following code in a file called @code{hello.scm} (this can be find in +@file{examples/scheme/hello.scm}). + +@smalllisp +#!/usr/local/bin/guile -s +!# + +(display "hello world") +(newline) +@end smalllisp + +Then run guile on it. One way to do so is to start up guile and load +this file: + +@smallexample +<shell-prompt> @kbd{guile} +guile> @kbd{(load "hello")} +@end smallexample + +Another way is to make the file executable and execute it directly. +Notice how Guile recognizes a @code{-s} option which tells it to run a +script and then exit. Guile also has a new type of block comment +enclosed by @code{#!} and @code{!#}, so that you can make executable +Scheme scripts with the standard UNIX @code{#!} mechanism. + +In the given example, the first line is used to invoke the Guile +interpreter (make sure you correct the path if you installed Guile in +something other than /usr/local/bin). Once Guile is invoked on this +file, it will understand that the first line is a comment. The comment +is then terminated with @code{!#} on the second line so as to not +interfere with the execution mechanism. + + +@subsection A bunch of operations in Scheme + +Here is some code you can type at the @code{guile>} prompt to see some +of the Scheme data types at work (mostly lists and vectors). I have +inserted brief comments @emph{before} each line of code explaining what +happens. + +@smalllisp +;; @r{make a list and bind it to the symbol @code{ls}} +guile> @kbd{(define ls (list 1 2 3 4 5 6 7))} + @result{} +;; @r{display the list} +guile> @kbd{ls} + @result{(1 2 3 4 5 6 7)} +;; @r{ask if @code{ls} is a vector; @code{#f} means it is not} +guile> @kbd{(vector? ls)} + @result{#f} +;; @r{ask if @code{ls} is a list; @code{#t} means it is} +guile> @kbd{(list? ls)} + @result{#t} +;; @r{ask for the length of @code{ls}} +guile> @kbd{(length ls)} + @result{7} +;; @r{pick out the first element of the list} +guile> @kbd{(car ls)} + @result{1} +;; @r{pick the rest of the list without the first element} +guile> @kbd{(cdr ls)} + @result{(2 3 4 5 6 7} +;; @r{this should pick out the 3rd element of the list} +guile> @kbd{(car (cdr (cdr ls)))} + @result{3} +;; @r{a shorthand for doing the same thing} +guile> @kbd{(caddr ls)} + @result{3} +;; @r{append the given list onto @code{ls}, print the result} +;; @r{@strong{NOTE:} the original list @code{ls} is @emph{not} modified} +guile> @kbd{(append ls (list 8 9 10))} + @result{(1 2 3 4 5 6 7 8 9 10)} +guile> @kbd{(reverse ls)} + @result{(10 9 8 7 6 5 4 3 2 1)} +;; @r{ask if 12 is in the list --- it obviously is not} +guile> @kbd{(memq 12 ls)} + @result{#f} +;; @r{ask if 4 is in the list --- returns the list from 4 on.} +;; @r{Notice that the result will behave as true in conditionals} +guile> @kbd{(memq 4 ls)} + @result{(4 5 6 7)} +;; @r{an @code{if} statement using the aforementioned result} +guile> @kbd{(if (memq 4 ls) + (display "hey, it's true!\n") + (display "dude, it's false\n"))} + @print{hey, it's true!} + @result{} +guile> @kbd{(if (memq 12 ls) + (display "hey, it's true!\n") + (display "dude, it's false\n"))} + @print{dude, it's false} + @result{} +guile> @kbd{(memq 4 (reverse ls))} + @result{(4 3 2 1)} +;; @r{make a smaller list @code{ls2} to work with} +guile> @kbd{(define ls2 (list 2 3 4))} +;; @r{make a list in which the function @code{sin} has been} +;; @r{applied to all elements of @code{ls2}} +guile> @kbd{(map sin ls2)} + @result{(0.909297426825682 0.141120008059867 -0.756802495307928)} +;; @r{make a list in which the squaring function has been} +;; @r{applied to all elements of @code{ls}} +guile> @kbd{(map (lambda (n) (expt n n)) ls)} + @result{(1 4 27 256 3125 46656 823543)} +@end smalllisp + +@smalllisp +;; @r{make a vector and bind it to the symbol @code{v}} +guile> @kbd{(define v #(1 2 3 4 5 6 7))} +guile> @kbd{v} + @result{#(1 2 3 4 5 6 7)} +guile> @kbd{(vector? v)} + @result{#t} +guile> @kbd{(list? v)} + @result{#f} +guile> @kbd{(vector-length v)} + @result{7} +;; @r{vector-ref allows you to pick out elements by index} +guile> @kbd{(vector-ref v 2)} + @result{3} +;; @r{play around with the vector: make it into a list, reverse} +;; @r{the list, go back to a vector and take the second element} +guile> @kbd{(vector-ref (list->vector (reverse (vector->list v))) 2)} + @result{5} +;; @r{this demonstrates that the entries in a vector do not have} +;; @r{to be of uniform type} +guile> @kbd{(vector-set! v 4 "hi there")} + @result{"hi there"} +guile> @kbd{v} + @result{#(1 2 3 4 "hi there" 6 7)} +@end smalllisp + + +@subsection Using recursion to process lists +@cindex recursion +@cindex list processing + +Here are some typical examples of using recursion to process a list. + +@smalllisp +;; @r{this is a rather trivial way of reversing a list} +(define (my-reverse l) + (if (null? l) + l + (append (my-reverse (cdr l)) (list (car l))))) +(my-reverse '(27 32 33 40)) +@result{(40 33 32 27)} +@end smalllisp + + +@subsection Processing matrices + +Suppose you have a matrix represented as a list of lists: + +@smalllisp +(define m + (list + (list 7 2 1 3 2 8 5 3 6) + (list 4 1 1 1 3 8 9 8 1) + (list 5 5 4 8 1 8 2 2 4))) +@end smalllisp + +Then you could apply a certain function to each element of the matrix in +the following manner: +@smalllisp +;; @r{apply the function func to the matrix m element-by-element;} +;; @r{return a matrix with the result.} +(define (process-matrix m func) + (map (lambda (l) + (map func l)) + m)) +@end smalllisp +Notice that I have used the Scheme @code{map} procedure because I am +interested in the matrix that results from the application of +@code{func}, rather than in the side effects associated with applying +@code{func}. + +This could be invoked with @code{(process-matrix m sin)} or +@code{(process-matrix m (lambda (x) (* x x)))}; for example: + +@smalllisp +(process-matrix m (lambda (x) (* x x))) +@result{((49 4 1 9 4 64 25 9 36) (16 1 1 1 9 64 81 64 1) (25 25 16 64 1 64 4 4 16))} +@end smalllisp + +To print a representation of the matrix, we could define a generalized +routine: +@smalllisp +;; @r{proc is a procedure to represent the single element,} +;; @r{row-proc is a procedure that is invoked after each row.} +;; @r{Example: proc could be (lambda (x) (begin (display x) (display " ")))} +;; @r{and row-proc could be (lambda (l) (display "\n"))} +(define (represent-matrix m proc row-proc) + (for-each (lambda (l) + (begin + (for-each proc l) + (row-proc l))) + m)) +@end smalllisp +@findex represent-matrix + +And then invoke it with +@smalllisp +(represent-matrix m + (lambda (x) (begin (display x) (display " "))) + (lambda (l) (begin (display "\n")))) +@print{7 2 1 3 2 8 5 3 6} +@print{4 1 1 1 3 8 9 8 1} +@print{5 5 4 8 1 8 2 2 4} +@end smalllisp + +@cindex objects + +Now we write a helper routine that uses Scheme @dfn{closures} to make +objects with state that then receive messages to draw little squares. +@cindex closures +@cindex syntactic closures + +But let us take it one step at a time. I will start by showing you a +simple example of object in Scheme. The object I make here represents a +cell, which could be a cell in a matrix. The cell responds to commands +to draw itself, to return the next cell, and so forth. @emph{Guile does +not currently have a Tk interface, so I will leave the hooks for +graphical rendering. In a future release of Guile I will add graphical +rendering messages to the cell object.} + +@smallexample +;; @r{cell-object.scm: routines for creating and manipulating cell objects} + +;; @r{(the-x, the-y) is the initial position of the cell.} +;; @r{the-color is a string representing a color; must be something Tk can grok.} +;; @r{square-size is the size of the square that gets drawn.} +;; @r{(sizex, sizey) is the size of the matrix.} +(define (MAKE-CELL the-x the-y the-color square-size sizex sizey) + (define (get-x) the-x) + (define (get-y) the-y) + + (define (set-x! new-x) + (set! the-x new-x) + the-x) + (define (set-y! new-y) + (set! the-y new-y) + the-y) + (define (get-color) the-color) + (define (set-color! new-color) + (set! the-color new-color) + the-color) + (define (next!) + (set! the-x (+ the-x 1)) + (if (>= the-x sizex) + (begin + (set! the-x 0) + (set! the-y (+ the-y 1)))) + (if (>= the-y sizey) + (begin + (display "CELL next!: value of y is too big; not changing it\n") + (set! the-y (- the-y 1)))) + (cons the-x the-y)) + (define (draw) + (let* ((x0 (* the-x square-size)) + (y0 (* the-y square-size)) + (x1 (+ x0 square-size)) + (y1 (+ y0 square-size))) + (display "I should draw a ") + (display the-color) + (display " rectangle with corners at ") + (display x0) (display y0) (display x1) (display y1) + )) + + ;; self is the dispatch procedure + (define (self message) + (case message + ((x) get-x) + ((y) get-y) + ((set-x!) set-x!) + ((set-y!) set-y!) + ((color) get-color) + ((set-color!) set-color!) + ((next!) next!) + ((draw) draw) + (else (error "CELL: Unknown message -> " message)))) + ;; and now return the dispatch procedure + self + ) +@end smallexample +@cindex cell-object +@findex MAKE-CELL + +What does this procedure do? It returns another procedure +(@code{self}) which receives a message (x, y, set-x!, set-y!, @dots{}) +and takes an action to return or modify its state. The state consists +of the values of variables @code{the-x}, @code{the-y}, @code{the-color} +and so forth. + +Here are some examples of how to use MAKE-CELL and the cell object it +creates: +@smallexample +(define c (MAKE-CELL 0 0 "red" 10 7 9)) + +;; @r{retrieve the x and y coordinates} +((c 'x)) +@result{0} +((c 'y)) +@result{0} +;; @r{change the x coordinate} +((c 'set-x!) 5) +@result{5} +((c 'x)) +@result{5} +;; @r{change the color} +((c 'color)) +@result{"red"} +((c 'set-color!) "green") +@result{"green"} +((c 'color)) +@result{"green"} +;; @r{now use the next! message to move to the next cell} +((c 'next!)) +@result{(6 . 0)} +((c 'x)) +@result{6} +((c 'y)) +@result{0} +;; @r{now make things wrap around} +((c 'next!)) +@result{(0 . 1)} +((c 'next!)) +@result{(1 . 1)} +((c 'next!)) +@result{(2 . 1)} +((c 'x)) +@result{2} +((c 'y)) +@result{1} +@end smallexample + +You will notice that expressions like @code{(c 'next)} return procedures +that do the job, so we have to use extra parentheses to make the job +happen. This syntax is rather awkward; one way around it is to define a +@code{send} procedure: + +@smallexample +;; @r{send makes object syntax a bit easier; instead of saying} +;; @r{ ((my-cell 'set-x!) 4)} +;; @r{you can say} +;; @r{ (send my-cell 'set-x! 4)} +(define (send obj . args) + (let ((first-eval (apply obj (list (car args))))) + (if (null? (cdr args)) + (first-eval) + (apply first-eval (cdr args))))) +@end smallexample +@findex send + +You can see that @code{send} passes the message to the object, making +sure that things are evaluated the proper number of times. You can now +type: + +@smallexample +(define c2 (MAKE-CELL 0 0 "red" 10 7 9)) +(send c2 'x) +@result{0} +(send c2 'set-x! 5) +@result{5} +(send c2 'color) +@result{"red"} +(send c2 'set-color! "green") +@result{"green"} +(send c2 'next!) +@result{(1 . 0)} +(send c2 'x) +@result{1} +(send c2 'y) +@result{0} +@end smallexample + +@cindex object-based programming +@cindex object-oriented programming + +This is the simplest way of implementing objects in Scheme, but it does +not really allow for full @emph{object-oriented programming} (for +example, there is no inheritance). But it is useful for +@emph{object-based programming}. + +Guile comes with a couple more complete object-oriented extensions to +Scheme: these are part of slib (@pxref{Object, , , slib, SLIB: the +portable Scheme library} and @pxref{Yasos, , , slib, SLIB: the portable +Scheme library}). + +@node Guile in a Library +@chapter Guile in a Library + +@iftex +@nobreak +@end iftex +In the previous chapters Guile was used to write programs entirely in +Scheme, and no C code was seen; but I have been claiming @emph{ad +nauseam} that Guile is an @emph{extension} language. Here we see how +that is done, and how that can be useful. +@cindex libguile +@cindex extending C programs + + +@menu +* Two world views:: +* What is libguile:: +* How to get started with libguile:: +* More interesting programming with libguile:: +* Further examples:: +@end menu + +@node Two world views +@section Two world views +@cindex master world + +In this manual, I usually jump into examples and explain them as you +type in the code; here I will digress and ramble for a few paragraphs to +set some concepts straight, and then let you type (or paste) in fun +examples. + +In 1995, I implemented a large program, @dfn{Gnudl}, using Guile quite +extensively. In the design phase of Gnudl, I found I had to make a +choice: should the fundamental data structures be C or Scheme data +structures? +@cindex gnudl +@cindex GNU Data Language +@cindex Galassi, Mark + +Guile allows C to see its data structures (scalar types, lists, vectors, +strings @dots{}). C also allows Guile to see its data structures. As a +large program designer, you have to decide which of those capabilities +to use. You have two main choices: + +@enumerate 1 +@item +You can write your software mostly in Scheme. In this case, your C +software will mostly parse the Scheme code with Guile calls, and provide +some new primitive procedures to be used by Scheme. This is what Gnudl +does. + +@item +You can write your software mostly in C, occasionally allowing Scheme +code to be parsed by Guile, either to allow the user to modify data +structures, or to parse a configuration file, @dots{} +@end enumerate + +Mixing the two approaches seems unwise: the overall layout would be +confusing. But who knows? There might be problems that are best solved +by a hybrid approach. Please let me know if you think of such a +problem. + +If you use the former approach, we will say that the @dfn{master world} +is Scheme, and the C routines serve Scheme and access Scheme data +structures. In the latter case, the master world is C, and Scheme +routines serve the C code and access C data structures. + +In both approaches the @code{libguile.a} library is the same, but a +predominantly different set of routines will be used. When we go +through examples of libguile use, we will point out which is the master +world in order to clarify these two approaches. + + +@node What is libguile +@section What is libguile +@cindex libguile +@cindex gh interface +@cindex scm interface + +@dfn{Libguile} is the library which allows C programs to start a Scheme +interpreter and execute Scheme code. There are also facilities in +libguile to make C data structures available to Scheme, and vice versa. + +The interface provided by the libguile C library is somewhat specific to +the implementation of the Scheme interpreter. This low-level libguile +interface is usually referred to as the @code{scm_} interface, since its +public calls (API) all have the @code{scm_} prefix. + +There is also a higher-level libguile interface, which is usually +referred to as the @code{gh_} interface (libGuile High). Its public +calls all have the @code{gh_} prefix. The @code{gh_} library interface +is designed to hide the implementation details, thus making it easier to +assimilate and portable to other underlying Scheme implementations. + +People extending Guile by adding bindings to C libraries (like OpenGL or +Rx) are encouraged to use the @code{gh_} interface, so their work will +be portable to other Scheme systems. The @code{gh_} interface should be +more stable, because it is simpler. + +The @code{scm_} interface is necessary if you want to poke into the +innards of Scheme data structures, or do anything else that is not +offered by the @code{gh_} interface. It is not covered in this +tutorial, but is covered extensively in @ref{Scheme data representation, +Guile Reference Manual, guile-ref, Guile Reference Manual}. + +This chapter gives a gentle introduction to the @code{gh_} interface, +presenting some @emph{hello world}-style programs which I wrote while +teaching myself to use libguile. +@cindex hello world + +The @cite{Guile Programmer's Manual} gives more examples of programs +written using libguile, illustrating diverse applications. You can also +consult my @emph{Gnudl} documentation at +@url{http://nis-www.lanl.gov/~rosalia/mydocs/} to see a large scale +project that uses C and Scheme code together. + + +@node How to get started with libguile +@section How to get started with libguile +@cindex learn0 + +Here is an elementary first program, @code{learn0}, to get going with +libguile. The program (which uses Scheme as a master world) is in a +single source file, @code{learn0.c}: + +@smallexample +/* @r{test the new libgh.a (Guile High-level library) with a trivial + program} */ + +#include <stdio.h> + +#include <guile/gh.h> + +void main_prog(int argc, char *argv[]); + +main(int argc, char *argv[]) +@{ + gh_enter(argc, argv, main_prog); +@} + +void main_prog(int argc, char *argv[]) +@{ + int done; + char input_str[200]; + + gh_eval_str("(display \"hello Guile\")"); + gh_eval_str("(newline)"); + + /* @r{for fun, evaluate some simple Scheme expressions here} */ + gh_eval_str("(define (square x) (* x x))"); + gh_eval_str("(define (fact n) (if (= n 1) 1 (* n (fact (- n 1)))))"); + gh_eval_str("(square 9)"); + + /* @r{now sit in a Scheme eval loop: I input the expressions, have + Guile evaluate them, and then get another expression.} */ + done = 0; + fputs("learn0> ", stdout); + while (fgets(input_str, 199, stdin) != NULL) @{ + gh_eval_str(input_str); + fputs("\nlearn0> ", stdout); + @} + + exit(0); +@} +@end smallexample + +If you name this program @code{learn0.c}, it can now be compiled with: +@smallexample +gcc -g -c learn0.c -o learn0.o +gcc -o learn0 learn0.o -lguile -lm +@end smallexample + +@c @emph{NOTE: If you are in the Guile development tree, you can simply do +@c ``cd doc/examples/c; make; ./learn0''.} + +The program is simple: it creates a Scheme interpreter, passes a couple +of strings to it that define new Scheme functions @code{square} and +@code{factorial}, and then a couple of strings that invoke those +functions. + +It then goes into a read-eval-print-loop (REPL), so you could type +one-line Scheme expressions to it and have them evaluated. For example: +@smallexample +<shell-prompt> ./learn0 +hello Guile +learn0> (display (sin 1.3)) +963.558185417193e-3 +learn0> (display (fact 10)) +3628800 +learn0> (quit) +<shell-prompt> +@end smallexample + +You should notice the key steps involved in this @code{learn0} program: + +@cartouche +@enumerate +@item +@code{#include <guile/gh.h>} +@item +You need to invoke the initialization routine @code{gh_enter()}. This +starts up a Scheme interpreter, handling many implementation-specific +details. +@item +Your main() function should be almost empty: the real main program goes +in a separate function main_prog() which is passed to gh_enter(). This +rather arcane convention is due to the way Guile's garbage collector +works: the whole program has to run in the dynamic context of +@code{gh_enter()}. +@item +You pass strings to the Scheme interpreter with the @code{gh_eval_str()} +routine. +@item +You link your program with @code{-lguile}. +@end enumerate +@end cartouche + + +@node More interesting programming with libguile +@section More interesting programming with libguile +@cindex learn1 +@cindex callback +@cindex builtin functions + +The @code{learn0} program shows how you can invoke Scheme commands from +a C program. This is not such a great achievement: the same could have +been done by opening a pipe to SCM or any other Scheme interpreter. + +A true extension language must allow @dfn{callbacks}. Callbacks allow +you to write C routines that can be invoked as Scheme procedures, thus +adding new primitive procedures to Scheme. This also means that a +Scheme procedure can modify a C data structure. + +Guile allows you to define new Scheme procedures in C, and provides a +mechanism to go back and forth between C and Scheme data types. + +Here is a second program, @code{learn1}, which demonstrates these +features. It is split into three source files: @code{learn1.c}, +@code{c_builtins.h} and @code{c_builtins.c}. I am including the code +here. +@c , but you might just want to look at the online source code and the +@c Makefile.am that come with Guile in the +@c @file{doc/examples/c} directory. + +Notice that @code{learn1} uses a Scheme master world, and the C routines +in @code{c_builtins.c} are simply adding new primitives to Scheme. + +@menu +* learn1.c:: +* c_builtins.h:: +* c_builtins.c:: +* What learn1 is doing:: +* Compiling and running learn1:: +@end menu + +@node learn1.c +@subsection learn1.c + +Here is @file{learn1.c}: +@smallexample +#include <stdio.h> + +#include <guile/gh.h> + +#include "c_builtins.h" + +void main_prog(int argc, char *argv[]); + +main(int argc, char *argv[]) +@{ + gh_enter(argc, argv, main_prog); +@} + +void main_prog(int argc, char *argv[]) +@{ + char input_str[200]; /* @r{ugly hack: assume strlen(line) < 200} */ + int done; + + /* @r{for fun, evaluate some simple Scheme expressions here} */ + gh_eval_str("(define (square x) (* x x))"); + gh_eval_str("(define (fact n) (if (= n 1) 1 (* n (fact (- n 1)))))"); + gh_eval_str("(square 9)"); + gh_eval_str("(fact 100)"); + + /* @r{now try to define some new builtins, coded in C, so that they are + available in Scheme.} */ + gh_new_procedure1_0("c-factorial", c_factorial); + gh_new_procedure1_0("c-sin", c_sin); + gh_new_procedure1_0("v-t", vector_test); + + /* @r{now sit in a Scheme eval loop: I input the expressions, have + Guile evaluate them, and then get another expression.} */ + done = 0; + fputs("learn1> ", stdout); + while (!done) @{ + if (gets(input_str) == NULL) @{ + done = 1; + @} else @{ + gh_eval_str(input_str); + fputs("learn1> ", stdout); + @} + @} + + exit(0); +@} +@end smallexample + +@node c_builtins.h +@subsection c_builtins.h + +Here is @file{c_builtins.h}: +@smallexample +/* @r{builtin function prototypes} */ + +#include <guile/gh.h> + +SCM c_factorial(SCM n); +SCM c_sin(SCM n); +SCM vector_test(SCM s_length); +@end smallexample + +@node c_builtins.c +@subsection c_builtins.c + +Here is @file{c_builtins.c}: +@smallexample +#include <stdio.h> +#include <math.h> + +#include <guile/gh.h> + +#include "c_builtins.h" + +/* @r{this is a factorial routine in C, made to be callable by Scheme} */ +SCM c_factorial(SCM s_n) +@{ + int i; + unsigned long result = 1, n; + + n = gh_scm2ulong(s_n); + + gh_defer_ints(); + for (i = 1; i <= n; ++i) @{ + result = result*i; + @} + gh_allow_ints(); + return gh_ulong2scm(result); +@} + +/* @r{a sin routine in C, callable from Scheme. it is named c_sin() to + distinguish it from the default Scheme sin function} */ +SCM c_sin(SCM s_x) +@{ + double x = gh_scm2double(s_x); + + return gh_double2scm(sin(x)); +@} + +/* @r{play around with vectors in Guile: this routine creates a vector of + the given length, initializes it all to zero except element 2 which + is set to 1.9.} */ +SCM vector_test(SCM s_length) +@{ + SCM xvec; + + c_length = gh_scm2ulong(s_length); + printf("requested length for vector: %ld\n", gh_scm2ulong(s_length)); + + /* create a vector */ + xvec = gh_make_vector(s_length, gh_double2scm(0.0)); + /* set the second element in it */ + gh_vector_set_x(xvec, gh_int2scm(2), gh_double2scm(1.9)); + + return xvec; +@} +@end smallexample + +@node What learn1 is doing +@subsection What learn1 is doing +@cindex registering callbacks +@cindex registering C functions +@cindex primitive procedures + +If you compare learn1 to learn0, you will find that learn1 uses a new +Guile construct: the function @code{gh_new_procedure()}, and its +siblings: + +@smallexample + /* @r{now try to define some new builtins, coded in C, so that they are + available in Scheme.} */ + gh_new_procedure1_0("c-factorial", c_factorial); + gh_new_procedure1_0("c-sin", c_sin); + gh_new_procedure1_0("v-t", vector_test); +@end smallexample + +It is clear that @code{gh_new_procedure()} adds a new builtin +routine written in C which can be invoked from Scheme. We can now +revise our checklist for programming with libguile, so it includes +adding callbacks. +@cindex libguile - step by step + +@cartouche +@enumerate +@item +@code{#include <guile/gh.h>} +@item +You need to invoke the initialization routine @code{gh_enter()}. This +starts up a Scheme interpreter, handling many details. +@item +Your main() function should be almost empty: the real main program goes +in a separate function main_prog() which is passed to gh_enter(). This +rather arcane convention is due to the way Guile's garbage collector +works: the whole program has to run in the dynamic context of +@code{gh_enter()}. +@item +You pass strings to the Scheme interpreter with the @code{gh_eval_str()} +routine. +@item +@strong{[new]} You can now define new builtin Scheme functions; +i.e. define new builtin Scheme functions, with the +@code{gh_new_procedure()} routine. +@item +You pass strings to the Scheme interpreter with the +@code{gh_eval_str()} routine. +@item +You link your program with @code{-lguile}. +@end enumerate +@end cartouche + +I breezed by the issue of how to write your C routines that are +registered to be called from Scheme. This is non-trivial, and is +discussed at length in the @cite{Guile Programmer's Manual}. + + +@node Compiling and running learn1 +@subsection Compiling and running learn1 + +@smallexample +gcc -g -c learn1.c -o learn1.o +gcc -g -c c_builtins.c -o c_builtins.o +gcc -o learn1 learn1.o c_builtins.o -lguile -lm +@end smallexample + +If you run @code{learn1}, it will prompt you for a one-line Scheme +expression, just as @code{learn0} did. The difference is that you can +use the new C builtin procedures (@code{c-factorial}, @code{c-sin}, +@code{v-t}). + +@smallexample +<shell-prompt> ./learn1 +welcome to Guile +hello Guile +learn1> (display (c-factorial 6)) +720 +learn1> (display (c-factorial 20)) +2192834560 +learn1> (display (c-factorial 100)) +0 +learn1> (display (c-sin 1.5)) +0.997494986604054 +learn1> (display (v-t 10)) +requested length for vector: 10 +#(0.0 0.0 1.9 0.0 0.0 0.0 0.0 0.0 0.0 0.0) +learn1> (display (v-t 15)) +requested length for vector: 15 +#(0.0 0.0 1.9 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0) +learn1> (quit) +<shell-prompt> +@end smallexample + +As you see, taking @code{(c-factorial 100)} does not use bignumbers and +returns a bogus answer. + +@node Further examples +@section Further examples + +Further ``idealized'' examples are included in the @code{doc/examples/c} +distribution. They include programs to: + +@c [FIXME: still have to write some of these; then I will revise the list.] + +@itemize @bullet +@item +Parse a startup file (C is the master world). +@item +Set up initial conditions for an n-body simulation (C is the master +world). +@item +Implement a Scheme interpreter with all of Guile's goodies, @emph{plus} +the readline library @emph{and} a fast Fourier transform routine +provided in C (Scheme is the master world). +@end itemize + +@node Regular Expression Support +@chapter Regular Expression Support + +@node UNIX System Programming +@chapter UNIX System Programming + +@node Where to find more Guile/Scheme resources +@chapter Where to find more Guile/Scheme resources + + +@node Concept Index +@unnumbered Concept Index + +@printindex cp + +@node Procedure and Macro Index +@unnumbered Procedure and Macro Index + +This is an alphabetical list of all the procedures and macros in Dominion. + +@printindex fn + +@node Variable Index +@unnumbered Variable Index + +This is an alphabetical list of the major global variables in Dominion. + +@printindex vr + +@node Type Index +@unnumbered Type Index + +This is an alphabetical list of the major data structures in Dominion. + +@printindex tp + +@contents + +@bye |