Constructing Procedures using Lambda Constructing Functions using Lambda Expressions - SICP Comparison Edition" /> 1.3.2   <span style="color:green">Constructing Procedures using Lambda</span> <span style="color:blue">Constructing Functions using Lambda Expressions </span> - SICP Comparison Edition
 Original JavaScript The general form of a let expression is (let (($var_1$ $exp_1$) ($var_2$ $exp_2$) $\vdots$ ($var_n$ $exp_n$)) $body$) which can be thought of as saying \begin{array}{ll} \mbox{let}\ &var_1\ \mbox{have the value}\ exp_\ \mbox{and}\\ &var_2\ \mbox{have the value}\ exp_2\ \mbox{and}\\ &\vdots\\ &var_n\ \mbox{have the value}\ exp_n\\ \mbox{in}\ & body \end{array} The first part of the let expression is a list of name-expression pairs. When the let is evaluated, each name is associated with the value of the corresponding expression. The body of the let is evaluated with these names bound as local variables. The way this happens is that the let expression is interpreted as an alternate syntax for ((lambda ($var_1$ $\ldots$ $var_n$) $body$) $exp_1$ $\vdots$ $exp_n$) No new mechanism is required in the interpreter in order to provide local variables. A let expression is simply syntactic sugar for the underlying lambda application. We can see from this equivalence that the scope of a variable specified by a let expression is the body of the let. This implies that: Let allows one to bind variables as locally as possible to where they are to be used. For example, if the value of x is 5, the value of the expression (+ (let ((x 3)) (+ x (* x 10))) x) is 38. Here, the x in the body of the let is 3, so the value of the let expression is 33. On the other hand, the x that is the second argument to the outermost + is still 5. The variables' values are computed outside the let. This matters when the expressions that provide the values for the local variables depend upon variables having the same names as the local variables themselves. For example, if the value of x is 2, the expression (let ((x 3) (y (+ x 2))) (* x y)) will have the value 12 because, inside the body of the let, x will be 3 and y will be 4 (which is the outer x plus 2). Sometimes we can use internal definitions to get the same effect as with let. For example, we could have defined the procedure f above as (define (f x y) (define a (+ 1 (* x y))) (define b (- 1 y)) (+ (* x (square a)) (* y b) (* a b))) We prefer, however, to use let in situations like this and to use internal define only for internal procedures.[6]
Original JavaScript

[1] In section 2.2.4, we will extend the syntax of lambda expressions to allow a block as the body rather than just an expression, as in function declaration statements.
[2] In JavaScript, there are subtle differences between the two versions: A function declaration statement is automatically hoisted'' (moved) to the beginning of the surrounding block or to the beginning of the program if it occurs outside of any block, whereas a constant declaration is not moved. Names declared with function declaration can be reassigned using assignment (section 3.1.1), whereas names declared with constant declarations can't. In this book, we avoid these features and treat a function declaration as equivalent to the corresponding constant declaration.
[3] It would be clearer and less intimidating to people learning Lisp JavaScript if a name term more obvious than lambda, such as make-procedure, lambda expression, such as function definition, were used. But the convention is firmly entrenched. very firmly entrenched, not just for Lisp and Scheme but also for JavaScript, Java and other languages, no doubt partly due to the influence of the Scheme editions of this book. The notation is adopted from the $\lambda$ calculus, a mathematical formalism introduced by the mathematical logician Alonzo Church (1941). Church developed the $\lambda$ calculus to provide a rigorous foundation for studying the notions of function and function application. The $\lambda$ calculus has become a basic tool for mathematical investigations of the semantics of programming languages.
[4] Note that a name declared in a block cannot be used before the declaration is fully evaluated, regardless of whether the same name is declared outside the block. Thus in the program below, the attempt to use the a declared at the top level to provide a value for the calculation of the b declared in f cannot work. const a = 1; function f(x) { const b = a + x; const a = 5; return a + b; } f(10); The program leads to an error, because the a in a + x is used before its declaration is evaluated. We will return to this program in section 4.1.6 (exercise 4.29), after we learn more about evaluation.
[5] The substitution model can be expanded to say that for a constant declaration, the value of the expression after = is substituted for the name before = in the rest of the block body (after the declaration), similar to the substitution of arguments for parameters in the evaluation of a function application.
[6] Understanding internal definitions well enough to be sure a program means what we intend it to mean requires a more elaborate model of the evaluation process than we have presented in this chapter. The subtleties do not arise with internal definitions of procedures, however. We will return to this issue in sections 3.2.4 and 4.1.6, after we learn more about the evaluation of blocks.
1.3.2   Constructing Procedures using Lambda Constructing Functions using Lambda Expressions