[1] In a real program we would probably use the block structure introduced in the last section to hide the definition of fact-iter: declaration of fact_iter:
Original JavaScript
(define (factorial n) (define (iter product counter) (if (> counter n) product (iter (* counter product) (+ counter 1)))) (iter 1 1)) function factorial(n) { function iter(product, counter) { return counter > n ? product : iter(counter * product, counter + 1); } return iter(1, 1); }
We avoided doing this here so as to minimize the number of things to think about at once.
[2] When we discuss the implementation of procedures functions on register machines in chapter 5, we will see that any iterative process can be realized in hardware as a machine that has a fixed set of registers and no auxiliary memory. In contrast, realizing a recursive process requires a machine that uses an auxiliary data structure known as a stack.
[3] Tail recursion has long been known as a compiler optimization trick. A coherent semantic basis for tail recursion was provided by Carl Hewitt (1977), who explained it in terms of the message-passing model of computation that we shall discuss in chapter 3. Inspired by this, Gerald Jay Sussman and Guy Lewis Steele Jr. (see Steele 1975) constructed a tail-recursive interpreter for Scheme. Steele later showed how tail recursion is a consequence of the natural way to compile procedure calls (Steele 1977). The IEEE standard for Scheme requires that Scheme implementations be tail-recursive.
[4] Tail recursion has long been known as a compiler optimization trick. A coherent semantic basis for tail recursion was provided by Carl Hewitt (1977), who explained it in terms of the message-passing model of computation that we shall discuss in chapter 3. Inspired by this, Gerald Jay Sussman and Guy Lewis Steele Jr. (see Steele 1975) constructed a tail-recursive interpreter for Scheme. Steele later showed how tail recursion is a consequence of the natural way to compile function calls (Steele 1977). The IEEE standard for Scheme requires that Scheme implementations be tail-recursive. The ECMA standard for JavaScript eventually followed suit with ECMAScript 2015 (ECMA 2015). Note, however, that as of this writing (2021), most implementations of JavaScript do not comply with this standard with respect to tail recursion.
[5] Exercise 4.11 explores JavaScript's while loops as syntactic sugar for functions that give rise to iterative processes. The full language JavaScript, like other conventional languages, features a plethora of syntactic forms, all of which can be expressed more uniformly in the language Lisp. This, together with the fact that these constructs typically involve semicolons whose placement rules are sometimes not obvious, led Alan Perlis to quip: Syntactic sugar causes cancer of the semicolon.
1.2.1  Linear Recursion and Iteration