Skip to content

Commit 5beeeca

Browse files
authored
Function bodies are blocks (#280)
* fixes #268 * exercise didn't make any sense any longer
1 parent ae51dfb commit 5beeeca

File tree

15 files changed

+521
-466
lines changed

15 files changed

+521
-466
lines changed

xml/chapter1/section2/subsection1.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ function factorial(n) {
165165
We avoided doing this here so as to minimize the number of things to
166166
think about at
167167
once.<LABEL NAME="foot:block-structured-factorial"/></FOOTNOTE>
168-
169168
<SNIPPET PAGE="34">
170169
<NAME>factorial_iterative_definition</NAME>
171170
<EXAMPLE>factorial_example</EXAMPLE>

xml/chapter1/section3/subsection2.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -749,10 +749,10 @@ function f(x, y) {
749749
</SCHEME>
750750
<JAVASCRIPT>
751751
Names that are declared with <JAVASCRIPTINLINE>const</JAVASCRIPTINLINE>
752-
directly inside of function declarations have the surrounding function as
752+
inside of a block have the body of the immediately surrounding block as
753753
their scope.<FOOTNOTE>
754754
<LABEL NAME="foot:tdz"/>
755-
Note that a name declared in a function using
755+
Note that a name declared in a block using
756756
<JAVASCRIPTINLINE>const</JAVASCRIPTINLINE> cannot be used before the
757757
declaration fully is evaluated, not even in the right-hand expression
758758
of the declaration itself, and regardless whether the same name is

xml/chapter1/section3/subsection3.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
<SCHEME>procedure that implements this strategy:</SCHEME>
8686
<JAVASCRIPT>function that implements this strategy:<FOOTNOTE>Note that we
8787
slightly extend the syntax of conditional statements described in
88-
section<SPACE/><REF NAME="sec:lambda"/> by allowing another conditional
88+
section<SPACE/><REF NAME="sec:lambda"/> by admitting another conditional
8989
statement in place of the block following
9090
<JAVASCRIPTINLINE>else</JAVASCRIPTINLINE>.</FOOTNOTE>
9191
</JAVASCRIPT>

xml/chapter3/section2/subsection1.xml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,8 @@ const square = x =&gt; x * x;
213213
<JAVASCRIPTINLINE>function</JAVASCRIPTINLINE> and
214214
<JAVASCRIPTINLINE>let</JAVASCRIPTINLINE>
215215
create declarations by adding bindings to frames.
216-
For declarations at the toplevel of the program, outside of any block
217-
or function body, we introduce a <EM>program environment</EM>,
216+
For declarations at the toplevel of the program, outside of any block,
217+
we introduce a <EM>program environment</EM>,
218218
consisting of a single frame<EMDASH/>the <EM>program
219219
frame</EM><EMDASH/>directly inside the global environment. To reduce
220220
clutter, after this figure, we will not display the global environment
@@ -479,10 +479,7 @@ const square = x =&gt; x * x;
479479
<JAVASCRIPT>simple function</JAVASCRIPT>
480480
</SPLITINLINE>
481481
application can be summarized by two
482-
rules:<SPLITINLINE><JAVASCRIPT><FOOTNOTE>
483-
In section<SPACE/><REF NAME="sec:env-internal-def"/>, we shall generalize
484-
the first rule to be able to handle functions whose bodies declare local
485-
names.</FOOTNOTE></JAVASCRIPT></SPLITINLINE>
482+
rules:
486483
<UL>
487484
<LI>
488485
A

xml/chapter3/section2/subsection4.xml

Lines changed: 108 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -21,77 +21,43 @@
2121
<JAVASCRIPT>
2222
<TEXT>
2323
Section<SPACE/><REF NAME="sec:env-apply-proc"/> describes the application
24-
of simple functions according to the substitution model, but fails to
25-
handle the case where the body of the function being applied contains
26-
constant, function or variable declarations, as in the functions
24+
of simple functions according to the environment model, but fails to
25+
handle proper blocks that contain contains constant, function or
26+
variable declarations, as the bodies of the functions
2727
<JAVASCRIPTINLINE>new_withdraw</JAVASCRIPTINLINE> and
2828
<JAVASCRIPTINLINE>make_account</JAVASCRIPTINLINE>
2929
of section<SPACE/><REF NAME="sec:local-state-variables"/>,
3030
in the function <JAVASCRIPTINLINE>make_rand</JAVASCRIPTINLINE>
3131
of section<SPACE/><REF NAME="sec:benefits-of-assignment"/>
3232
and in both versions of the factorial function
3333
of section<SPACE/><REF NAME="sec:costs-of-assignment"/>.
34-
Our treatment of the declaration of local names within function bodies
34+
Our treatment of the declaration of local names within blocks
3535
is similar to the treatment of declarations of global names, as for
3636
example the name <JAVASCRIPTINLINE>square</JAVASCRIPTINLINE> in
3737
section<SPACE/><REF NAME="sec:env-model-rules"/>. We explained
3838
that the names declared in the program are added to the program
3939
frame. More precisely, before the program gets evaluated, we identify
40-
the names that are declared in the program at toplevel. These names
41-
are all added to the program frame, and then the program gets evaluated
42-
with respect to the program environment. Initially, before the program
43-
runs, these names refer to a special value
40+
the names that are declared in the program at toplevel (outside of any
41+
block). These names are all added to the program frame, and then the
42+
program gets evaluated with respect to the program environment.
43+
Initially, before the program runs, these names refer to a special value
4444
<LATEXINLINE>$\textit{unassigned}$</LATEXINLINE>, and any attempt to
4545
access the value of a name that refers to
4646
<LATEXINLINE>$\textit{unassigned}$</LATEXINLINE> leads to an error.
4747
Constant and variable declarations can then be handled like assignments
4848
in section<SPACE/><REF NAME="sec:env-local-state"/>.
4949
</TEXT>
5050
<TEXT>
51-
Similar to names that are declared at toplevel, we simply add the
52-
names declared locally in a function body to the relevant
53-
environment frame
54-
before we evaluate the body. The relevant environment frame
55-
here is of course the new frame that binds the function's parameters
56-
to the values of the arguments. This leads to the final, definitive
57-
version of the first of the two rules in
58-
section<SPACE/><REF NAME="sec:env-model-rules"/> that summarize
59-
the environment model of function application. The second rule
60-
is copied here for completeness; it hasn<APOS/>t changed.
61-
<UL>
62-
<LI>
63-
A function object is applied to a set of arguments by constructing a
64-
frame, in which we create variable bindings for the parameters of the
65-
function to the arguments of the call, <EM>and constant/variable
66-
bindings for the local constants/variable declarations in the body
67-
of the function,</EM> and then evaluating the body in the context of
68-
the new environment constructed. The new frame has as its enclosing
69-
environment the environment part of the function object being
70-
applied. <EM>The local constant/variable names intially refer to
71-
the value <LATEXINLINE>$\textit{unassigned}$</LATEXINLINE>, before
72-
the body is evaluated.</EM>
73-
<INDEX>function
74-
<SUBINDEX>creating with lambda</SUBINDEX></INDEX>
75-
<!--\indcodeplus{lambda}{expression}[value of]-->
76-
</LI>
77-
<LI>
78-
A function is created by evaluating a
79-
lambda expression relative to a given environment. The resulting
80-
function object is a pair consisting of the text of the lambda
81-
expression and a pointer to the environment in which the function
82-
was created.
83-
</LI>
84-
</UL>
85-
We apply the same idea to names that are declared within blocks, such
86-
as the consequent or alternative block of conditional statements, which
87-
we introduced in section<SPACE/><REF NAME="sec:lambda"/>: A block
88-
is evaluated by extending the current environment with a new frame.
89-
The constant/variable names declared within the block intially refer
90-
to the value <LATEXINLINE>$\textit{unassigned}$</LATEXINLINE>, before
91-
the body of the block is evaluated.<FOOTNOTE>Equipped with a deeper
92-
understanding of the scope of names, we can now explain why the program
93-
in footnote<SPACE/><REF NAME="foot:tdz"/> of chapter 1 goes
94-
wrong.</FOOTNOTE>
51+
In order to evaluate a block in a given environment, we extend the
52+
environment by a new frame that contains all names declared locally
53+
(outside of nested blocks) in the block body. These names intially refer
54+
to the value <LATEXINLINE>$\textit{unassigned}$</LATEXINLINE>, when the
55+
evaluation of the body commences. The evaluation of local constant
56+
and variable declarations then re-assign the names to the left of the
57+
equal sign, as if the declaration was an assignment.<FOOTNOTE>Equipped
58+
with a deeper understanding of the scope of names, we can now explain
59+
why the program in footnote<SPACE/><REF NAME="foot:tdz"/> of chapter 1
60+
goes wrong.</FOOTNOTE>
9561
</TEXT>
9662
</JAVASCRIPT>
9763
</SPLIT>
@@ -225,21 +191,21 @@ function sqrt(x) {
225191
<JAVASCRIPT>program</JAVASCRIPT>
226192
</SPLITINLINE>
227193
environment, in which the parameter <SCHEMEINLINE>x</SCHEMEINLINE> is bound
228-
<SPLITINLINE>
194+
to 2.
195+
<SPLIT>
229196
<SCHEME>
230-
to 2.
197+
The body of sqrt was then evaluated in E1. Since the first expression
198+
in the body of <SCHEMEINLINE>sqrt</SCHEMEINLINE> is
231199
</SCHEME>
232200
<JAVASCRIPT>
233-
to 2, and in which the locally declared names
234-
<JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>,
235-
<JAVASCRIPTINLINE>improve</JAVASCRIPTINLINE> and
236-
<JAVASCRIPTINLINE>sqrt_iter</JAVASCRIPTINLINE> are bound to
237-
the value <LATEXINLINE>$\textit{unassigned}$</LATEXINLINE>.
201+
The body of <SCHEMEINLINE>sqrt</SCHEMEINLINE> was then evaluated in
202+
E1. That body in this case is a block with local
203+
function declarations and therefore we extended E1 with a new frame for
204+
those declarations, resulting in the new environment E2. The body
205+
of the block was then evaluated in E2. Since the first statement
206+
in the body is
238207
</JAVASCRIPT>
239-
</SPLITINLINE>
240-
The body of <SCHEMEINLINE>sqrt</SCHEMEINLINE> was then evaluated in
241-
E1. Since the first expression in the body of
242-
<SCHEMEINLINE>sqrt</SCHEMEINLINE> is
208+
</SPLIT>
243209
<SNIPPET EVAL="no">
244210
<REQUIRES>abs_definition</REQUIRES>
245211
<REQUIRES>square_definition</REQUIRES>
@@ -253,38 +219,31 @@ function good_enough(guess) {
253219
}
254220
</JAVASCRIPT>
255221
</SNIPPET>
256-
evaluating this expression defined the
257-
<SPLITINLINE>
258-
<SCHEME>procedure</SCHEME>
259-
<JAVASCRIPT>function</JAVASCRIPT>
260-
</SPLITINLINE>
261-
<SPLITINLINE>
262-
<SCHEME><SCHEMEINLINE>good-enough?</SCHEMEINLINE></SCHEME>
263-
<JAVASCRIPT><JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE></JAVASCRIPT>
264-
</SPLITINLINE>
265-
in the environment<SPACE/>E1.
266222
<SPLIT>
267223
<SCHEME>
268-
To<SPACE/>be more precise, the
269-
symbol
270-
<SPLITINLINE>
271-
<SCHEME><SCHEMEINLINE>good-enough?</SCHEMEINLINE></SCHEME>
272-
<JAVASCRIPT><JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>
273-
</JAVASCRIPT>
274-
</SPLITINLINE>
275-
was added to the first frame of E1, bound to a
276-
<SPLITINLINE>
277-
<SCHEME>procedure</SCHEME>
278-
<JAVASCRIPT>function</JAVASCRIPT>
279-
</SPLITINLINE>
224+
evaluating this expression defined the procedure
225+
<SCHEMEINLINE>good-enough?</SCHEMEINLINE>
226+
in the environment<SPACE/>E1.
227+
</SCHEME>
228+
<JAVASCRIPT>
229+
evaluating this declaration created the function
230+
<JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>
231+
in the environment<SPACE/>E2.
232+
</JAVASCRIPT>
233+
</SPLIT>
234+
<SPLIT>
235+
<SCHEME>
236+
To<SPACE/>be more precise, the symbol
237+
<SCHEMEINLINE>good-enough?</SCHEMEINLINE> was added to the first frame
238+
of E1, bound to a procedure
280239
object whose associated environment is E1.
281240
</SCHEME>
282241
<JAVASCRIPT>
283242
To<SPACE/>be more precise, the value
284243
<LATEXINLINE>$\textit{unassigned}$</LATEXINLINE>
285244
for the symbol <JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>
286-
in the first frame of E1 is bound to a function
287-
object whose associated environment is E1.
245+
in the first frame of E2 was replaced by a function
246+
object whose associated environment is E2.
288247
</JAVASCRIPT>
289248
</SPLIT>
290249
Similarly,
@@ -295,10 +254,10 @@ function good_enough(guess) {
295254
</SPLITINLINE>
296255
were defined as
297256
<SPLITINLINE>
298-
<SCHEME>procedures</SCHEME>
299-
<JAVASCRIPT>functions</JAVASCRIPT>
257+
<SCHEME>procedures in E1.</SCHEME>
258+
<JAVASCRIPT>functions in E2.</JAVASCRIPT>
300259
</SPLITINLINE>
301-
in E1. For conciseness,
260+
For conciseness,
302261
<SPLITINLINE>
303262
<SCHEME>
304263
figure<SPACE/><REF NAME="fig:sqrt-internal_scheme"/>
@@ -331,18 +290,28 @@ function good_enough(guess) {
331290
<JAVASCRIPT><JAVASCRIPTINLINE>sqrt_iter(1.0)</JAVASCRIPTINLINE>
332291
</JAVASCRIPT>
333292
</SPLITINLINE>
334-
was evaluated, still in environment E1. So the
293+
was evaluated, still in environment
294+
<SPLITINLINE>
295+
<SCHEME>E1.</SCHEME>
296+
<JAVASCRIPT>E2.</JAVASCRIPT>
297+
</SPLITINLINE>
298+
So the
335299
<SPLITINLINE>
336300
<SCHEME>procedure</SCHEME>
337301
<JAVASCRIPT>function</JAVASCRIPT>
338302
</SPLITINLINE>
339303
object bound to
340304
<SPLITINLINE>
341-
<SCHEME><SCHEMEINLINE>sqrt-iter</SCHEMEINLINE></SCHEME>
342-
<JAVASCRIPT><JAVASCRIPTINLINE>sqrt_iter</JAVASCRIPTINLINE></JAVASCRIPT>
305+
<SCHEME><SCHEMEINLINE>sqrt-iter</SCHEMEINLINE>
306+
in E1 was called with 1 as an argument. This created an environment E2
307+
in which
308+
</SCHEME>
309+
<JAVASCRIPT><JAVASCRIPTINLINE>sqrt_iter</JAVASCRIPTINLINE>
310+
in E2 was called with 1 as an argument. This created an environment E3
311+
in which
312+
</JAVASCRIPT>
343313
</SPLITINLINE>
344-
in E1 was called with 1 as an argument. This created an environment E2 in
345-
which <SCHEMEINLINE>guess</SCHEMEINLINE>, the parameter of
314+
<SCHEMEINLINE>guess</SCHEMEINLINE>, the parameter of
346315
<SPLITINLINE>
347316
<SCHEME><SCHEMEINLINE>sqrt-iter</SCHEMEINLINE>,</SCHEME>
348317
<JAVASCRIPT><JAVASCRIPTINLINE>sqrt_iter</JAVASCRIPTINLINE>,</JAVASCRIPT>
@@ -358,17 +327,29 @@ function good_enough(guess) {
358327
<SCHEME><SCHEMEINLINE>good-enough?</SCHEMEINLINE></SCHEME>
359328
<JAVASCRIPT><JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE></JAVASCRIPT>
360329
</SPLITINLINE>
361-
with the value of <SCHEMEINLINE>guess</SCHEMEINLINE> (from E2) as the
362-
argument for
330+
with the value of <SCHEMEINLINE>guess</SCHEMEINLINE>
363331
<SPLITINLINE>
364-
<SCHEME><SCHEMEINLINE>good-enough?</SCHEMEINLINE>.</SCHEME>
365-
<JAVASCRIPT><JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>.</JAVASCRIPT>
332+
<SCHEME>
333+
(from E2) as the argument for
334+
<SCHEMEINLINE>good-enough?</SCHEMEINLINE>.
335+
</SCHEME>
336+
<JAVASCRIPT>
337+
(from E3) as the argument for
338+
<JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>.
339+
</JAVASCRIPT>
366340
</SPLITINLINE>
367-
This set up another environment, E3, in which
368-
<SCHEMEINLINE>guess</SCHEMEINLINE> (the parameter of
341+
This set up another environment,
369342
<SPLITINLINE>
370-
<SCHEME><SCHEMEINLINE>good-enough?</SCHEMEINLINE>)</SCHEME>
371-
<JAVASCRIPT><JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>)</JAVASCRIPT>
343+
<SCHEME>
344+
E3, in which
345+
<SCHEMEINLINE>guess</SCHEMEINLINE> (the parameter of
346+
<SCHEMEINLINE>good-enough?</SCHEMEINLINE>)
347+
</SCHEME>
348+
<JAVASCRIPT>
349+
E4, in which
350+
<SCHEMEINLINE>guess</SCHEMEINLINE> (the parameter of
351+
<JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>)
352+
</JAVASCRIPT>
372353
</SPLITINLINE>
373354
is bound to 1. Although
374355
<SPLITINLINE>
@@ -381,22 +362,23 @@ function good_enough(guess) {
381362
<JAVASCRIPT><JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE></JAVASCRIPT>
382363
</SPLITINLINE>
383364
both have a parameter named <SCHEMEINLINE>guess</SCHEMEINLINE>, these are two
384-
distinct local variables located in different frames. Also, E2 and E3 both
385-
have E1 as their enclosing environment, because the
386-
<SPLITINLINE>
387-
<SCHEME><SCHEMEINLINE>sqrt-iter</SCHEMEINLINE></SCHEME>
388-
<JAVASCRIPT><JAVASCRIPTINLINE>sqrt_iter</JAVASCRIPTINLINE></JAVASCRIPT>
389-
</SPLITINLINE>
390-
and
391-
<SPLITINLINE>
392-
<SCHEME><SCHEMEINLINE>good-enough?</SCHEMEINLINE></SCHEME>
393-
<JAVASCRIPT><JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE></JAVASCRIPT>
394-
</SPLITINLINE>
395-
<SPLITINLINE>
396-
<SCHEME>procedures</SCHEME>
397-
<JAVASCRIPT>functions</JAVASCRIPT>
398-
</SPLITINLINE>
399-
both have E1 as their environment part. One consequence of this is that the
365+
distinct local variables located in different frames.
366+
<SPLIT>
367+
<SCHEME>
368+
Also, E2 and E3 both have E1 as their enclosing environment, because the
369+
<SCHEMEINLINE>sqrt-iter</SCHEMEINLINE> and
370+
<SCHEMEINLINE>good-enough?</SCHEMEINLINE> procedures
371+
both have E1 as their environment part.
372+
</SCHEME>
373+
<JAVASCRIPT>
374+
Also, E3 and E4 both have E2 as their enclosing environment, because the
375+
<JAVASCRIPT><JAVASCRIPTINLINE>sqrt_iter</JAVASCRIPTINLINE></JAVASCRIPT>
376+
and
377+
<JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>
378+
both have E2 as their environment part.
379+
</JAVASCRIPT>
380+
</SPLIT>
381+
One consequence of this is that the
400382
symbol <SCHEMEINLINE>x</SCHEMEINLINE> that appears in the body of
401383
<SPLITINLINE>
402384
<SCHEME><SCHEMEINLINE>good-enough?</SCHEMEINLINE></SCHEME>
@@ -440,10 +422,10 @@ function good_enough(guess) {
440422
</SPLITINLINE>
441423
names will be bound in the frame that the
442424
<SPLITINLINE>
443-
<SCHEME>procedure</SCHEME>
444-
<JAVASCRIPT>function</JAVASCRIPT>
425+
<SCHEME>procedure creates when it is run,</SCHEME>
426+
<JAVASCRIPT>block creates when it is evaluated,</JAVASCRIPT>
445427
</SPLITINLINE>
446-
creates when it is run, rather than being bound in the
428+
rather than being bound in the
447429
<SPLITINLINE>
448430
<SCHEME>global</SCHEME>
449431
<JAVASCRIPT>program</JAVASCRIPT>
@@ -461,14 +443,14 @@ function good_enough(guess) {
461443
<SCHEME>procedure,</SCHEME>
462444
<JAVASCRIPT>function,</JAVASCRIPT>
463445
</SPLITINLINE>
464-
simply by using parameter names as free variables. This is because the
465-
body of the local
446+
simply by using parameter names as free variables. This is
447+
because the body of the local
466448
<SPLITINLINE>
467449
<SCHEME>procedure</SCHEME>
468450
<JAVASCRIPT>function</JAVASCRIPT>
469451
</SPLITINLINE>
470-
is evaluated in an environment that is subordinate to the evaluation
471-
environment for the enclosing
452+
is evaluated in an environment that is subordinate to the
453+
evaluation environment for the enclosing
472454
<SPLITINLINE>
473455
<SCHEME>procedure.</SCHEME>
474456
<JAVASCRIPT>function.</JAVASCRIPT>

0 commit comments

Comments
 (0)