Commit | Line | Data |
---|---|---|
a0e07ba4 NJ |
1 | @page |
2 | @node Binding Constructs | |
3 | @chapter Definitions and Variable Bindings | |
4 | ||
5 | @c FIXME::martin: Review me! | |
6 | ||
7 | Scheme supports the definition of variables in different contexts. | |
8 | Variables can be defined at the top level, so that they are visible in | |
9 | the entire program, and variables can be defined locally to procedures | |
10 | and expressions. This is important for modularity and data abstraction. | |
11 | ||
12 | @menu | |
13 | * Top Level:: Top level variable definitions. | |
14 | * Local Bindings:: Local variable bindings. | |
15 | * Internal Definitions:: Internal definitions. | |
16 | * Binding Reflection:: Querying variable bindings. | |
17 | @end menu | |
18 | ||
19 | ||
20 | @node Top Level | |
21 | @section Top Level Variable Definitions | |
22 | ||
23 | @c FIXME::martin: Review me! | |
24 | ||
25 | @cindex variable definition | |
26 | ||
27 | On the top level of a program (e.g. when not inside of a procedure | |
28 | definition or a @code{let}, @code{let*} or @code{letrec} expression), a | |
29 | definition of the form | |
30 | ||
31 | @lisp | |
32 | (define a 1) | |
33 | @end lisp | |
34 | ||
35 | @noindent | |
36 | defines a variable called @var{a} and sets it to the value 1. When the | |
37 | variable already was bound with a @code{define} expression, the above | |
38 | form is completely equivalent to | |
39 | ||
40 | @lisp | |
41 | (set! a 1) | |
42 | @end lisp | |
43 | ||
44 | @noindent | |
45 | that means that @code{define} can be used interchangeably with | |
46 | @code{set!} when at the top level of the REPL or a Scheme source file. | |
47 | But note that a @code{set!} is not allowed if the variable was not bound | |
48 | before. | |
49 | ||
50 | Attention: definitions inside local binding constructs (@pxref{Local | |
51 | Bindings}) act differently (@pxref{Internal Definitions}). | |
52 | ||
53 | ||
54 | @node Local Bindings | |
55 | @section Local Variable Bindings | |
56 | ||
57 | @c FIXME::martin: Review me! | |
58 | ||
59 | @cindex local bindings | |
60 | @cindex local variables | |
61 | ||
62 | As opposed to definitions at the top level, which are visible in the | |
63 | whole program (or current module, when Guile modules are used), it is | |
64 | also possible to define variables which are only visible in a | |
65 | well-defined part of the program. Normally, this part of a program | |
66 | will be a procedure or a subexpression of a procedure. | |
67 | ||
68 | With the constructs for local binding (@code{let}, @code{let*} and | |
69 | @code{letrec}), the Scheme language has a block structure like most | |
70 | other programming languages since the days of @sc{Algol 60}. Readers | |
71 | familiar to languages like C or Java should already be used to this | |
72 | concept, but the family of @code{let} expressions has a few properties | |
73 | which are well worth knowing. | |
74 | ||
75 | The first local binding construct is @code{let}. The other constructs | |
76 | @code{let*} and @code{letrec} are specialized versions for usage where | |
77 | using plain @code{let} is a bit inconvenient. | |
78 | ||
79 | @deffn syntax let bindings body | |
80 | @var{bindings} has the form | |
81 | ||
82 | @lisp | |
83 | ((@var{variable1} @var{init1}) @dots{}) | |
84 | @end lisp | |
85 | ||
86 | that is zero or more two-element lists of a variable and an arbitrary | |
87 | expression each. All @var{variable} names must be distinct. | |
88 | ||
89 | A @code{let} expression is evaluated as follows. | |
90 | ||
91 | @itemize @bullet | |
92 | @item | |
93 | All @var{init} expressions are evaluated. | |
94 | ||
95 | @item | |
96 | New storage is allocated for the @var{variables}. | |
97 | ||
98 | @item | |
99 | The values of the @var{init} expressions are stored into the variables. | |
100 | ||
101 | @item | |
102 | The expressions in @var{body} are evaluated in order, and the value of | |
103 | the last expression is returned as the value of the @code{let} | |
104 | expression. | |
105 | ||
106 | @item | |
107 | The storage for the @var{variables} is freed. | |
108 | @end itemize | |
109 | ||
110 | The @var{init} expressions are not allowed to refer to any of the | |
111 | @var{variables}. | |
112 | @end deffn | |
113 | ||
114 | @deffn syntax let* bindings body | |
115 | Similar to @code{let}, but the variable bindings are performed | |
116 | sequentially, that means that all @var{init} expression are allowed to | |
117 | use the variables defined on their left in the binding list. | |
118 | ||
119 | A @code{let*} expression can always be expressed with nested @code{let} | |
120 | expressions. | |
121 | ||
122 | @lisp | |
123 | (let* ((a 1) (b a)) | |
124 | b) | |
125 | @equiv{} | |
126 | (let ((a 1)) | |
127 | (let ((b a)) | |
128 | b)) | |
129 | @end lisp | |
130 | @end deffn | |
131 | ||
132 | @deffn syntax letrec bindings body | |
133 | Similar to @code{let}, but it is possible to refer to the @var{variable} | |
134 | from lambda expression created in any of the @var{inits}. That is, | |
135 | procedures created in the @var{init} expression can recursively refer to | |
136 | the defined variables. | |
137 | ||
138 | @lisp | |
139 | (letrec ((even? | |
140 | (lambda (n) | |
141 | (if (zero? n) | |
142 | #t | |
143 | (odd? (- n 1))))) | |
144 | (odd? | |
145 | (lambda (n) | |
146 | (if (zero? n) | |
147 | #f | |
148 | (even? (- n 1)))))) | |
149 | (even? 88)) | |
150 | @result{} | |
151 | #t | |
152 | @end lisp | |
153 | @end deffn | |
154 | ||
155 | There is also an alternative form of the @code{let} form, which is used | |
156 | for expressing iteration. Because of the use as a looping construct, | |
157 | this form (the @dfn{named let}) is documented in the section about | |
158 | iteration (@pxref{while do, Iteration}) | |
159 | ||
160 | @node Internal Definitions | |
161 | @section Internal definitions | |
162 | ||
163 | @c FIXME::martin: Review me! | |
164 | ||
165 | A @code{define} form which appears inside the body of a @code{lambda}, | |
166 | @code{let}, @code{let*}, @code{letrec} or equivalent expression is | |
167 | called an @dfn{internal definition}. An internal definition differs | |
168 | from a top level definition (@pxref{Top Level}), because the definition | |
169 | is only visible inside the complete body of the enclosing form. Let us | |
170 | examine the following example. | |
171 | ||
172 | @lisp | |
173 | (let ((frumble "froz")) | |
174 | (define banana (lambda () (apple 'peach))) | |
175 | (define apple (lambda (x) x)) | |
176 | (banana)) | |
177 | @result{} | |
178 | peach | |
179 | @end lisp | |
180 | ||
181 | Here the enclosing form is a @code{let}, so the @code{define}s in the | |
182 | @code{let}-body are internal definitions. Because the scope of the | |
183 | internal definitions is the @strong{complete} body of the | |
184 | @code{let}-expression, the @code{lambda}-expression which gets bound | |
185 | to the variable @code{banana} may refer to the variable @code{apple}, | |
186 | even thogh it's definition appears lexically @emph{after} the definition | |
187 | of @code{banana}. This is because a sequence of internal definition | |
188 | acts as if it were a @code{letrec} expression. | |
189 | ||
190 | @lisp | |
191 | (let () | |
192 | (define a 1) | |
193 | (define b 2) | |
194 | (+ a b)) | |
195 | @end lisp | |
196 | ||
197 | @noindent | |
198 | is equivalent to | |
199 | ||
200 | @lisp | |
201 | (let () | |
202 | (letrec ((a 1) (b 2)) | |
203 | (+ a b))) | |
204 | @end lisp | |
205 | ||
206 | Another noteworthy difference to top level definitions is that within | |
207 | one group of internal definitions all variable names must be distinct. | |
208 | That means where on the top level a second define for a given variable | |
209 | acts like a @code{set!}, an exception is thrown for internal definitions | |
210 | with duplicate bindings. | |
211 | ||
212 | @c FIXME::martin: The following is required by R5RS, but Guile does not | |
213 | @c signal an error. Document it anyway, saying that Guile is sloppy? | |
214 | ||
215 | @c Internal definitions are only allowed at the beginning of the body of an | |
216 | @c enclosing expression. They may not be mixed with other expressions. | |
217 | ||
218 | @c @lisp | |
219 | @c (let () | |
220 | @c (define a 1) | |
221 | @c a | |
222 | @c (define b 2) | |
223 | @c b) | |
224 | @c @end lisp | |
225 | ||
226 | @node Binding Reflection | |
227 | @section Querying variable bindings | |
228 | ||
229 | Guile provides a procedure for checking wehther a symbol is bound in the | |
230 | top level environment. If you want to test whether a symbol is locally | |
231 | bound in expression, you can use the @code{bound?} macro from the module | |
232 | @code{(ice-9 optargs)}, documented in @ref{Optional Arguments}. | |
233 | ||
234 | @c NJFIXME explain [env] | |
235 | @deffn primitive defined? sym [env] | |
236 | Return @code{#t} if @var{sym} is defined in the top-level environment. | |
237 | @end deffn | |
238 | ||
239 | ||
240 | @c Local Variables: | |
241 | @c TeX-master: "guile.texi" | |
242 | @c End: |