mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-17 17:20:29 +02:00
Fix typo.
This commit is contained in:
parent
1afff62054
commit
20ec6e2638
1 changed files with 0 additions and 242 deletions
|
@ -1,242 +0,0 @@
|
|||
@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 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 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:
|
Loading…
Add table
Add a link
Reference in a new issue