mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-07-02 07:40:30 +02:00
* 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'.
This commit is contained in:
parent
c07b3fefa5
commit
65f7a6501c
4 changed files with 290 additions and 7 deletions
|
@ -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>
|
2001-04-17 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
|
||||||
|
|
||||||
* scheme-control.texi (Multiple Values): Documented concept of
|
* scheme-control.texi (Multiple Values): Documented concept of
|
||||||
|
|
|
@ -2,6 +2,13 @@
|
||||||
@node Binding Constructs
|
@node Binding Constructs
|
||||||
@chapter Definitions and Variable Bindings
|
@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
|
@menu
|
||||||
* Top Level:: Top level variable definitions.
|
* Top Level:: Top level variable definitions.
|
||||||
* Local Bindings:: Local variable bindings.
|
* Local Bindings:: Local variable bindings.
|
||||||
|
@ -13,18 +20,217 @@
|
||||||
@node Top Level
|
@node Top Level
|
||||||
@section Top Level Variable Definitions
|
@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
|
@node Local Bindings
|
||||||
@section Local Variable 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
|
@node Internal Definitions
|
||||||
@section 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
|
@node Binding Reflection
|
||||||
@section Querying variable bindings
|
@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]
|
@c NJFIXME explain [env]
|
||||||
@deffn primitive defined? sym [env]
|
@deffn primitive defined? sym [env]
|
||||||
Return @code{#t} if @var{sym} is defined in the top-level environment.
|
Return @code{#t} if @var{sym} is defined in the top-level environment.
|
||||||
|
|
|
@ -174,6 +174,7 @@ If used without expressions, @code{#f} is returned.
|
||||||
|
|
||||||
@cindex iteration
|
@cindex iteration
|
||||||
@cindex looping
|
@cindex looping
|
||||||
|
@cindex named let
|
||||||
|
|
||||||
Scheme has only few iteration mechanisms, mainly because iteration in
|
Scheme has only few iteration mechanisms, mainly because iteration in
|
||||||
Scheme programs is normally expressed using recursion. Nevertheless,
|
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.
|
is @code{#f} right from the start.
|
||||||
@end deffn
|
@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
|
@node Continuations
|
||||||
@section Continuations
|
@section Continuations
|
||||||
|
|
|
@ -36,8 +36,8 @@ clutter the global name space.
|
||||||
@cindex name space - private
|
@cindex name space - private
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Scheme and modules::
|
* Scheme and modules:: How modules are handled in standard Scheme.
|
||||||
* The Guile module system::
|
* The Guile module system:: How Guile does it.
|
||||||
* Dynamic Libraries:: Loading libraries of compiled code at run time.
|
* Dynamic Libraries:: Loading libraries of compiled code at run time.
|
||||||
* Dynamic Linking from Marius::
|
* Dynamic Linking from Marius::
|
||||||
@end menu
|
@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
|
For example, the file @file{random.scm} in the SLIB package contains the
|
||||||
line
|
line
|
||||||
|
|
||||||
@smalllisp
|
@smalllisp
|
||||||
(provide 'random)
|
(provide 'random)
|
||||||
@end smalllisp
|
@end smalllisp
|
||||||
|
|
||||||
so to use its procedures, a user would type
|
so to use its procedures, a user would type
|
||||||
|
|
||||||
@smalllisp
|
@smalllisp
|
||||||
(require 'random)
|
(require 'random)
|
||||||
@end smalllisp
|
@end smalllisp
|
||||||
|
|
||||||
and they would magically become available, @emph{but still have the same
|
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
|
names!} So this method is nice, but not as good as a full-featured
|
||||||
module system.
|
module system.
|
||||||
|
@ -84,13 +88,17 @@ is called @code{ice-9}.
|
||||||
|
|
||||||
So for example, the SLIB interface, contained in
|
So for example, the SLIB interface, contained in
|
||||||
@file{$srcdir/ice-9/slib.scm}, starts out with
|
@file{$srcdir/ice-9/slib.scm}, starts out with
|
||||||
|
|
||||||
@smalllisp
|
@smalllisp
|
||||||
(define-module (ice-9 slib))
|
(define-module (ice-9 slib))
|
||||||
@end smalllisp
|
@end smalllisp
|
||||||
|
|
||||||
and a user program can use
|
and a user program can use
|
||||||
|
|
||||||
@smalllisp
|
@smalllisp
|
||||||
(use-modules (ice-9 slib))
|
(use-modules (ice-9 slib))
|
||||||
@end smalllisp
|
@end smalllisp
|
||||||
|
|
||||||
to have access to all procedures and variables defined within the slib
|
to have access to all procedures and variables defined within the slib
|
||||||
module with @code{(define-public ...)}.
|
module with @code{(define-public ...)}.
|
||||||
|
|
||||||
|
@ -99,11 +107,13 @@ So here are the functions involved:
|
||||||
@deffn syntax define-module module-specification
|
@deffn syntax define-module module-specification
|
||||||
@var{module-specification} is of the form @code{(hierarchy file)}. One
|
@var{module-specification} is of the form @code{(hierarchy file)}. One
|
||||||
example of this is
|
example of this is
|
||||||
|
|
||||||
@smalllisp
|
@smalllisp
|
||||||
(use-modules (ice-9 slib))
|
(define-module (ice-9 slib))
|
||||||
@end smalllisp
|
@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
|
@end deffn
|
||||||
@c end
|
@c end
|
||||||
|
|
||||||
|
@ -118,11 +128,13 @@ module.
|
||||||
@deffn syntax use-modules module-specification
|
@deffn syntax use-modules module-specification
|
||||||
@var{module-specification} is of the form @code{(hierarchy file)}. One
|
@var{module-specification} is of the form @code{(hierarchy file)}. One
|
||||||
example of this is
|
example of this is
|
||||||
|
|
||||||
@smalllisp
|
@smalllisp
|
||||||
(use-modules (ice-9 slib))
|
(use-modules (ice-9 slib))
|
||||||
@end smalllisp
|
@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}.
|
@var{module-specification}.
|
||||||
@end deffn
|
@end deffn
|
||||||
@c end
|
@c end
|
||||||
|
@ -150,6 +162,8 @@ Guile's support for multi threaded execution (@pxref{Scheduling}).
|
||||||
@item (ice-9 slib)
|
@item (ice-9 slib)
|
||||||
This module contains hooks for using Aubrey Jaffer's portable Scheme
|
This module contains hooks for using Aubrey Jaffer's portable Scheme
|
||||||
library SLIB from Guile (@pxref{SLIB}).
|
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)
|
@item (ice-9 jacal)
|
||||||
This module contains hooks for using Aubrey Jaffer's symbolic math
|
This module contains hooks for using Aubrey Jaffer's symbolic math
|
||||||
packge Jacal from Guile (@pxref{JACAL}).
|
packge Jacal from Guile (@pxref{JACAL}).
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue