summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Grabmüller <mgrabmue@cs.tu-berlin.de>2001-04-19 21:35:44 +0000
committerMartin Grabmüller <mgrabmue@cs.tu-berlin.de>2001-04-19 21:35:44 +0000
commit65f7a6501c87bb4454c2146a81d13a57efb8378f (patch)
treed35a01832f7c8cb3ca44aec742029e048ba6816e
parentc07b3fefa5efb7a4f9419260285c8229b1e92487 (diff)
downloadguile-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/ChangeLog20
-rw-r--r--doc/scheme-binding.texi206
-rw-r--r--doc/scheme-control.texi43
-rw-r--r--doc/scheme-modules.texi28
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}).