Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion xml/chapter1/section2/subsection1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ function factorial(n) {
We avoided doing this here so as to minimize the number of things to
think about at
once.<LABEL NAME="foot:block-structured-factorial"/></FOOTNOTE>

<SNIPPET PAGE="34">
<NAME>factorial_iterative_definition</NAME>
<EXAMPLE>factorial_example</EXAMPLE>
Expand Down
4 changes: 2 additions & 2 deletions xml/chapter1/section3/subsection2.xml
Original file line number Diff line number Diff line change
Expand Up @@ -749,10 +749,10 @@ function f(x, y) {
</SCHEME>
<JAVASCRIPT>
Names that are declared with <JAVASCRIPTINLINE>const</JAVASCRIPTINLINE>
directly inside of function declarations have the surrounding function as
inside of a block have the body of the immediately surrounding block as
their scope.<FOOTNOTE>
<LABEL NAME="foot:tdz"/>
Note that a name declared in a function using
Note that a name declared in a block using
<JAVASCRIPTINLINE>const</JAVASCRIPTINLINE> cannot be used before the
declaration fully is evaluated, not even in the right-hand expression
of the declaration itself, and regardless whether the same name is
Expand Down
2 changes: 1 addition & 1 deletion xml/chapter1/section3/subsection3.xml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
<SCHEME>procedure that implements this strategy:</SCHEME>
<JAVASCRIPT>function that implements this strategy:<FOOTNOTE>Note that we
slightly extend the syntax of conditional statements described in
section<SPACE/><REF NAME="sec:lambda"/> by allowing another conditional
section<SPACE/><REF NAME="sec:lambda"/> by admitting another conditional
statement in place of the block following
<JAVASCRIPTINLINE>else</JAVASCRIPTINLINE>.</FOOTNOTE>
</JAVASCRIPT>
Expand Down
9 changes: 3 additions & 6 deletions xml/chapter3/section2/subsection1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ const square = x =&gt; x * x;
<JAVASCRIPTINLINE>function</JAVASCRIPTINLINE> and
<JAVASCRIPTINLINE>let</JAVASCRIPTINLINE>
create declarations by adding bindings to frames.
For declarations at the toplevel of the program, outside of any block
or function body, we introduce a <EM>program environment</EM>,
For declarations at the toplevel of the program, outside of any block,
we introduce a <EM>program environment</EM>,
consisting of a single frame<EMDASH/>the <EM>program
frame</EM><EMDASH/>directly inside the global environment. To reduce
clutter, after this figure, we will not display the global environment
Expand Down Expand Up @@ -479,10 +479,7 @@ const square = x =&gt; x * x;
<JAVASCRIPT>simple function</JAVASCRIPT>
</SPLITINLINE>
application can be summarized by two
rules:<SPLITINLINE><JAVASCRIPT><FOOTNOTE>
In section<SPACE/><REF NAME="sec:env-internal-def"/>, we shall generalize
the first rule to be able to handle functions whose bodies declare local
names.</FOOTNOTE></JAVASCRIPT></SPLITINLINE>
rules:
<UL>
<LI>
A
Expand Down
234 changes: 108 additions & 126 deletions xml/chapter3/section2/subsection4.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,77 +21,43 @@
<JAVASCRIPT>
<TEXT>
Section<SPACE/><REF NAME="sec:env-apply-proc"/> describes the application
of simple functions according to the substitution model, but fails to
handle the case where the body of the function being applied contains
constant, function or variable declarations, as in the functions
of simple functions according to the environment model, but fails to
handle proper blocks that contain contains constant, function or
variable declarations, as the bodies of the functions
<JAVASCRIPTINLINE>new_withdraw</JAVASCRIPTINLINE> and
<JAVASCRIPTINLINE>make_account</JAVASCRIPTINLINE>
of section<SPACE/><REF NAME="sec:local-state-variables"/>,
in the function <JAVASCRIPTINLINE>make_rand</JAVASCRIPTINLINE>
of section<SPACE/><REF NAME="sec:benefits-of-assignment"/>
and in both versions of the factorial function
of section<SPACE/><REF NAME="sec:costs-of-assignment"/>.
Our treatment of the declaration of local names within function bodies
Our treatment of the declaration of local names within blocks
is similar to the treatment of declarations of global names, as for
example the name <JAVASCRIPTINLINE>square</JAVASCRIPTINLINE> in
section<SPACE/><REF NAME="sec:env-model-rules"/>. We explained
that the names declared in the program are added to the program
frame. More precisely, before the program gets evaluated, we identify
the names that are declared in the program at toplevel. These names
are all added to the program frame, and then the program gets evaluated
with respect to the program environment. Initially, before the program
runs, these names refer to a special value
the names that are declared in the program at toplevel (outside of any
block). These names are all added to the program frame, and then the
program gets evaluated with respect to the program environment.
Initially, before the program runs, these names refer to a special value
<LATEXINLINE>$\textit{unassigned}$</LATEXINLINE>, and any attempt to
access the value of a name that refers to
<LATEXINLINE>$\textit{unassigned}$</LATEXINLINE> leads to an error.
Constant and variable declarations can then be handled like assignments
in section<SPACE/><REF NAME="sec:env-local-state"/>.
</TEXT>
<TEXT>
Similar to names that are declared at toplevel, we simply add the
names declared locally in a function body to the relevant
environment frame
before we evaluate the body. The relevant environment frame
here is of course the new frame that binds the function's parameters
to the values of the arguments. This leads to the final, definitive
version of the first of the two rules in
section<SPACE/><REF NAME="sec:env-model-rules"/> that summarize
the environment model of function application. The second rule
is copied here for completeness; it hasn<APOS/>t changed.
<UL>
<LI>
A function object is applied to a set of arguments by constructing a
frame, in which we create variable bindings for the parameters of the
function to the arguments of the call, <EM>and constant/variable
bindings for the local constants/variable declarations in the body
of the function,</EM> and then evaluating the body in the context of
the new environment constructed. The new frame has as its enclosing
environment the environment part of the function object being
applied. <EM>The local constant/variable names intially refer to
the value <LATEXINLINE>$\textit{unassigned}$</LATEXINLINE>, before
the body is evaluated.</EM>
<INDEX>function
<SUBINDEX>creating with lambda</SUBINDEX></INDEX>
<!--\indcodeplus{lambda}{expression}[value of]-->
</LI>
<LI>
A function is created by evaluating a
lambda expression relative to a given environment. The resulting
function object is a pair consisting of the text of the lambda
expression and a pointer to the environment in which the function
was created.
</LI>
</UL>
We apply the same idea to names that are declared within blocks, such
as the consequent or alternative block of conditional statements, which
we introduced in section<SPACE/><REF NAME="sec:lambda"/>: A block
is evaluated by extending the current environment with a new frame.
The constant/variable names declared within the block intially refer
to the value <LATEXINLINE>$\textit{unassigned}$</LATEXINLINE>, before
the body of the block is evaluated.<FOOTNOTE>Equipped with a deeper
understanding of the scope of names, we can now explain why the program
in footnote<SPACE/><REF NAME="foot:tdz"/> of chapter 1 goes
wrong.</FOOTNOTE>
In order to evaluate a block in a given environment, we extend the
environment by a new frame that contains all names declared locally
(outside of nested blocks) in the block body. These names intially refer
to the value <LATEXINLINE>$\textit{unassigned}$</LATEXINLINE>, when the
evaluation of the body commences. The evaluation of local constant
and variable declarations then re-assign the names to the left of the
equal sign, as if the declaration was an assignment.<FOOTNOTE>Equipped
with a deeper understanding of the scope of names, we can now explain
why the program in footnote<SPACE/><REF NAME="foot:tdz"/> of chapter 1
goes wrong.</FOOTNOTE>
</TEXT>
</JAVASCRIPT>
</SPLIT>
Expand Down Expand Up @@ -225,21 +191,21 @@ function sqrt(x) {
<JAVASCRIPT>program</JAVASCRIPT>
</SPLITINLINE>
environment, in which the parameter <SCHEMEINLINE>x</SCHEMEINLINE> is bound
<SPLITINLINE>
to 2.
<SPLIT>
<SCHEME>
to 2.
The body of sqrt was then evaluated in E1. Since the first expression
in the body of <SCHEMEINLINE>sqrt</SCHEMEINLINE> is
</SCHEME>
<JAVASCRIPT>
to 2, and in which the locally declared names
<JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>,
<JAVASCRIPTINLINE>improve</JAVASCRIPTINLINE> and
<JAVASCRIPTINLINE>sqrt_iter</JAVASCRIPTINLINE> are bound to
the value <LATEXINLINE>$\textit{unassigned}$</LATEXINLINE>.
The body of <SCHEMEINLINE>sqrt</SCHEMEINLINE> was then evaluated in
E1. That body in this case is a block with local
function declarations and therefore we extended E1 with a new frame for
those declarations, resulting in the new environment E2. The body
of the block was then evaluated in E2. Since the first statement
in the body is
</JAVASCRIPT>
</SPLITINLINE>
The body of <SCHEMEINLINE>sqrt</SCHEMEINLINE> was then evaluated in
E1. Since the first expression in the body of
<SCHEMEINLINE>sqrt</SCHEMEINLINE> is
</SPLIT>
<SNIPPET EVAL="no">
<REQUIRES>abs_definition</REQUIRES>
<REQUIRES>square_definition</REQUIRES>
Expand All @@ -253,38 +219,31 @@ function good_enough(guess) {
}
</JAVASCRIPT>
</SNIPPET>
evaluating this expression defined the
<SPLITINLINE>
<SCHEME>procedure</SCHEME>
<JAVASCRIPT>function</JAVASCRIPT>
</SPLITINLINE>
<SPLITINLINE>
<SCHEME><SCHEMEINLINE>good-enough?</SCHEMEINLINE></SCHEME>
<JAVASCRIPT><JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE></JAVASCRIPT>
</SPLITINLINE>
in the environment<SPACE/>E1.
<SPLIT>
<SCHEME>
To<SPACE/>be more precise, the
symbol
<SPLITINLINE>
<SCHEME><SCHEMEINLINE>good-enough?</SCHEMEINLINE></SCHEME>
<JAVASCRIPT><JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>
</JAVASCRIPT>
</SPLITINLINE>
was added to the first frame of E1, bound to a
<SPLITINLINE>
<SCHEME>procedure</SCHEME>
<JAVASCRIPT>function</JAVASCRIPT>
</SPLITINLINE>
evaluating this expression defined the procedure
<SCHEMEINLINE>good-enough?</SCHEMEINLINE>
in the environment<SPACE/>E1.
</SCHEME>
<JAVASCRIPT>
evaluating this declaration created the function
<JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>
in the environment<SPACE/>E2.
</JAVASCRIPT>
</SPLIT>
<SPLIT>
<SCHEME>
To<SPACE/>be more precise, the symbol
<SCHEMEINLINE>good-enough?</SCHEMEINLINE> was added to the first frame
of E1, bound to a procedure
object whose associated environment is E1.
</SCHEME>
<JAVASCRIPT>
To<SPACE/>be more precise, the value
<LATEXINLINE>$\textit{unassigned}$</LATEXINLINE>
for the symbol <JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>
in the first frame of E1 is bound to a function
object whose associated environment is E1.
in the first frame of E2 was replaced by a function
object whose associated environment is E2.
</JAVASCRIPT>
</SPLIT>
Similarly,
Expand All @@ -295,10 +254,10 @@ function good_enough(guess) {
</SPLITINLINE>
were defined as
<SPLITINLINE>
<SCHEME>procedures</SCHEME>
<JAVASCRIPT>functions</JAVASCRIPT>
<SCHEME>procedures in E1.</SCHEME>
<JAVASCRIPT>functions in E2.</JAVASCRIPT>
</SPLITINLINE>
in E1. For conciseness,
For conciseness,
<SPLITINLINE>
<SCHEME>
figure<SPACE/><REF NAME="fig:sqrt-internal_scheme"/>
Expand Down Expand Up @@ -331,18 +290,28 @@ function good_enough(guess) {
<JAVASCRIPT><JAVASCRIPTINLINE>sqrt_iter(1.0)</JAVASCRIPTINLINE>
</JAVASCRIPT>
</SPLITINLINE>
was evaluated, still in environment E1. So the
was evaluated, still in environment
<SPLITINLINE>
<SCHEME>E1.</SCHEME>
<JAVASCRIPT>E2.</JAVASCRIPT>
</SPLITINLINE>
So the
<SPLITINLINE>
<SCHEME>procedure</SCHEME>
<JAVASCRIPT>function</JAVASCRIPT>
</SPLITINLINE>
object bound to
<SPLITINLINE>
<SCHEME><SCHEMEINLINE>sqrt-iter</SCHEMEINLINE></SCHEME>
<JAVASCRIPT><JAVASCRIPTINLINE>sqrt_iter</JAVASCRIPTINLINE></JAVASCRIPT>
<SCHEME><SCHEMEINLINE>sqrt-iter</SCHEMEINLINE>
in E1 was called with 1 as an argument. This created an environment E2
in which
</SCHEME>
<JAVASCRIPT><JAVASCRIPTINLINE>sqrt_iter</JAVASCRIPTINLINE>
in E2 was called with 1 as an argument. This created an environment E3
in which
</JAVASCRIPT>
</SPLITINLINE>
in E1 was called with 1 as an argument. This created an environment E2 in
which <SCHEMEINLINE>guess</SCHEMEINLINE>, the parameter of
<SCHEMEINLINE>guess</SCHEMEINLINE>, the parameter of
<SPLITINLINE>
<SCHEME><SCHEMEINLINE>sqrt-iter</SCHEMEINLINE>,</SCHEME>
<JAVASCRIPT><JAVASCRIPTINLINE>sqrt_iter</JAVASCRIPTINLINE>,</JAVASCRIPT>
Expand All @@ -358,17 +327,29 @@ function good_enough(guess) {
<SCHEME><SCHEMEINLINE>good-enough?</SCHEMEINLINE></SCHEME>
<JAVASCRIPT><JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE></JAVASCRIPT>
</SPLITINLINE>
with the value of <SCHEMEINLINE>guess</SCHEMEINLINE> (from E2) as the
argument for
with the value of <SCHEMEINLINE>guess</SCHEMEINLINE>
<SPLITINLINE>
<SCHEME><SCHEMEINLINE>good-enough?</SCHEMEINLINE>.</SCHEME>
<JAVASCRIPT><JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>.</JAVASCRIPT>
<SCHEME>
(from E2) as the argument for
<SCHEMEINLINE>good-enough?</SCHEMEINLINE>.
</SCHEME>
<JAVASCRIPT>
(from E3) as the argument for
<JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>.
</JAVASCRIPT>
</SPLITINLINE>
This set up another environment, E3, in which
<SCHEMEINLINE>guess</SCHEMEINLINE> (the parameter of
This set up another environment,
<SPLITINLINE>
<SCHEME><SCHEMEINLINE>good-enough?</SCHEMEINLINE>)</SCHEME>
<JAVASCRIPT><JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>)</JAVASCRIPT>
<SCHEME>
E3, in which
<SCHEMEINLINE>guess</SCHEMEINLINE> (the parameter of
<SCHEMEINLINE>good-enough?</SCHEMEINLINE>)
</SCHEME>
<JAVASCRIPT>
E4, in which
<SCHEMEINLINE>guess</SCHEMEINLINE> (the parameter of
<JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>)
</JAVASCRIPT>
</SPLITINLINE>
is bound to 1. Although
<SPLITINLINE>
Expand All @@ -381,22 +362,23 @@ function good_enough(guess) {
<JAVASCRIPT><JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE></JAVASCRIPT>
</SPLITINLINE>
both have a parameter named <SCHEMEINLINE>guess</SCHEMEINLINE>, these are two
distinct local variables located in different frames. Also, E2 and E3 both
have E1 as their enclosing environment, because the
<SPLITINLINE>
<SCHEME><SCHEMEINLINE>sqrt-iter</SCHEMEINLINE></SCHEME>
<JAVASCRIPT><JAVASCRIPTINLINE>sqrt_iter</JAVASCRIPTINLINE></JAVASCRIPT>
</SPLITINLINE>
and
<SPLITINLINE>
<SCHEME><SCHEMEINLINE>good-enough?</SCHEMEINLINE></SCHEME>
<JAVASCRIPT><JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE></JAVASCRIPT>
</SPLITINLINE>
<SPLITINLINE>
<SCHEME>procedures</SCHEME>
<JAVASCRIPT>functions</JAVASCRIPT>
</SPLITINLINE>
both have E1 as their environment part. One consequence of this is that the
distinct local variables located in different frames.
<SPLIT>
<SCHEME>
Also, E2 and E3 both have E1 as their enclosing environment, because the
<SCHEMEINLINE>sqrt-iter</SCHEMEINLINE> and
<SCHEMEINLINE>good-enough?</SCHEMEINLINE> procedures
both have E1 as their environment part.
</SCHEME>
<JAVASCRIPT>
Also, E3 and E4 both have E2 as their enclosing environment, because the
<JAVASCRIPT><JAVASCRIPTINLINE>sqrt_iter</JAVASCRIPTINLINE></JAVASCRIPT>
and
<JAVASCRIPTINLINE>good_enough</JAVASCRIPTINLINE>
both have E2 as their environment part.
</JAVASCRIPT>
</SPLIT>
One consequence of this is that the
symbol <SCHEMEINLINE>x</SCHEMEINLINE> that appears in the body of
<SPLITINLINE>
<SCHEME><SCHEMEINLINE>good-enough?</SCHEMEINLINE></SCHEME>
Expand Down Expand Up @@ -440,10 +422,10 @@ function good_enough(guess) {
</SPLITINLINE>
names will be bound in the frame that the
<SPLITINLINE>
<SCHEME>procedure</SCHEME>
<JAVASCRIPT>function</JAVASCRIPT>
<SCHEME>procedure creates when it is run,</SCHEME>
<JAVASCRIPT>block creates when it is evaluated,</JAVASCRIPT>
</SPLITINLINE>
creates when it is run, rather than being bound in the
rather than being bound in the
<SPLITINLINE>
<SCHEME>global</SCHEME>
<JAVASCRIPT>program</JAVASCRIPT>
Expand All @@ -461,14 +443,14 @@ function good_enough(guess) {
<SCHEME>procedure,</SCHEME>
<JAVASCRIPT>function,</JAVASCRIPT>
</SPLITINLINE>
simply by using parameter names as free variables. This is because the
body of the local
simply by using parameter names as free variables. This is
because the body of the local
<SPLITINLINE>
<SCHEME>procedure</SCHEME>
<JAVASCRIPT>function</JAVASCRIPT>
</SPLITINLINE>
is evaluated in an environment that is subordinate to the evaluation
environment for the enclosing
is evaluated in an environment that is subordinate to the
evaluation environment for the enclosing
<SPLITINLINE>
<SCHEME>procedure.</SCHEME>
<JAVASCRIPT>function.</JAVASCRIPT>
Expand Down
Loading