diff options
author | Martin Grabmüller <mgrabmue@cs.tu-berlin.de> | 2001-04-19 21:35:44 +0000 |
---|---|---|
committer | Martin Grabmüller <mgrabmue@cs.tu-berlin.de> | 2001-04-19 21:35:44 +0000 |
commit | 65f7a6501c87bb4454c2146a81d13a57efb8378f (patch) | |
tree | d35a01832f7c8cb3ca44aec742029e048ba6816e | |
parent | c07b3fefa5efb7a4f9419260285c8229b1e92487 (diff) | |
download | guile-65f7a6501c87bb4454c2146a81d13a57efb8378f.tar.gz |
* scheme-control.texi (while do): Added documentation for named
let.
* scheme-binding.texi (Internal Definitions): New explanation of
`Internal Definitions'.
(Top Level): Documented behaviour of top level definitions.
(Binding Constructs): New introductory text.
(Local Bindings): Explain concept of local bindings. Document
let, let* and letrec.
* scheme-modules.texi (Modules): Added menu descriptions.
(Scheme and modules, The Guile module system): Some whitespace
cleanup
(The Guile module system): Layout fixes, docstring fix for
`define-module'.
-rw-r--r-- | doc/ChangeLog | 20 | ||||
-rw-r--r-- | doc/scheme-binding.texi | 206 | ||||
-rw-r--r-- | doc/scheme-control.texi | 43 | ||||
-rw-r--r-- | doc/scheme-modules.texi | 28 |
4 files changed, 290 insertions, 7 deletions
diff --git a/doc/ChangeLog b/doc/ChangeLog index a3e0f1a4a..86a6f39e6 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,23 @@ +2001-04-19 Martin Grabmueller <mgrabmue@cs.tu-berlin.de> + + * scheme-control.texi (while do): Added documentation for named + let. + + * scheme-binding.texi (Internal Definitions): New explanation of + `Internal Definitions'. + (Top Level): Documented behaviour of top level definitions. + (Binding Constructs): New introductory text. + (Local Bindings): Explain concept of local bindings. Document + let, let* and letrec. + +2001-04-18 Martin Grabmueller <mgrabmue@cs.tu-berlin.de> + + * scheme-modules.texi (Modules): Added menu descriptions. + (Scheme and modules, The Guile module system): Some whitespace + cleanup + (The Guile module system): Layout fixes, docstring fix for + `define-module'. + 2001-04-17 Martin Grabmueller <mgrabmue@cs.tu-berlin.de> * scheme-control.texi (Multiple Values): Documented concept of diff --git a/doc/scheme-binding.texi b/doc/scheme-binding.texi index b6bbe7447..94d0587bd 100644 --- a/doc/scheme-binding.texi +++ b/doc/scheme-binding.texi @@ -2,6 +2,13 @@ @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. @@ -13,18 +20,217 @@ @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 wher +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 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. diff --git a/doc/scheme-control.texi b/doc/scheme-control.texi index 129a1143d..f5f0191ee 100644 --- a/doc/scheme-control.texi +++ b/doc/scheme-control.texi @@ -174,6 +174,7 @@ If used without expressions, @code{#f} is returned. @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, @@ -201,6 +202,48 @@ 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 diff --git a/doc/scheme-modules.texi b/doc/scheme-modules.texi index a02229bfb..1cdc6445c 100644 --- a/doc/scheme-modules.texi +++ b/doc/scheme-modules.texi @@ -36,8 +36,8 @@ clutter the global name space. @cindex name space - private @menu -* Scheme and modules:: -* The Guile module system:: +* 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. * Dynamic Linking from Marius:: @end menu @@ -55,13 +55,17 @@ Library files in SLIB @emph{provide} a feature, and when user programs 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. @@ -84,13 +88,17 @@ is called @code{ice-9}. So for example, the SLIB interface, contained in @file{$srcdir/ice-9/slib.scm}, starts out with + @smalllisp (define-module (ice-9 slib)) @end smalllisp + and a user program can use + @smalllisp (use-modules (ice-9 slib)) @end smalllisp + to have access to all procedures and variables defined within the slib module with @code{(define-public ...)}. @@ -99,11 +107,13 @@ So here are the functions involved: @deffn syntax define-module module-specification @var{module-specification} is of the form @code{(hierarchy file)}. One example of this is + @smalllisp -(use-modules (ice-9 slib)) +(define-module (ice-9 slib)) @end smalllisp -define-module makes this module available to Guile programs under the -given @var{module-specification}. + +@code{define-module} makes this module available to Guile programs under +the given @var{module-specification}. @end deffn @c end @@ -118,11 +128,13 @@ module. @deffn syntax use-modules module-specification @var{module-specification} is of the form @code{(hierarchy file)}. One example of this is + @smalllisp (use-modules (ice-9 slib)) @end smalllisp -use-modules allows the current Guile program to use all publicly defined -procedures and variables in the module denoted by + +@code{use-modules} allows the current Guile program to use all publicly +defined procedures and variables in the module denoted by @var{module-specification}. @end deffn @c end @@ -150,6 +162,8 @@ Guile's support for multi threaded execution (@pxref{Scheduling}). @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}). |