Combinations Applications and Return Statements - SICP Comparison Edition" /> 5.5.3   Compiling <span style="color:green"> Combinations </span> <span style="color:blue"> Applications and Return Statements </span> - SICP Comparison Edition
Original JavaScript
Original JavaScript
Original JavaScript

[1] Because the execution of a function body always ends with a return, there is no need here for a mechanism like the return_undefined entry point from section 5.4.1.
[2] Elsewhere in the compiler, all saves and restores of registers are generated by preserving to preserve a register's value across a sequence of instructions by saving it before those instructions and restoring it after—for example over the evaluation of the predicate of a conditional. But this mechanism cannot generate instructions to save and restore continue for a function application and the corresponding return, because these are compiled separately and are not contiguous. Instead, these saves and restores must be explicitly generated by compile_fun_appl and compile_return_statement.
[3] Actually, we signal an error when the target is not val and the linkage is return, "return", since the only place we request returnlinkages a "return" linkage is in compiling procedures, return expressions, and our convention is that procedures functions return their values in val.
[4] Making a compiler generate tail-recursive code might seem like a straightforward idea. But code is desirable, especially in the functional paradigm. However, compilers for common languages, including C and Pascal, C and C++, do not always do this, and therefore these languages cannot represent iterative processes in terms of procedure function call alone. The difficulty with tail recursion in these languages is that their implementations use the stack to store procedure function arguments and local variables names as well as return addresses. The Scheme JavaScript implementations described in this book store arguments and variables names in memory to be garbage-collected. The reason for using the stack for variables names and arguments is that it avoids the need for garbage collection in languages that would not otherwise require it, and is generally believed to be more efficient. Sophisticated Lisp compilers can, in fact, use the stack for arguments without destroying tail recursion. (See Hanson 1990 for a description.) There is also some debate about whether stack allocation is actually more efficient than garbage collection in the first place, but the details seem to hinge on fine points of computer architecture. (See Appel 1987 and Miller and Rozas 1994 for opposing views on this issue.)
[5] The variable constant all-regs all_regs is bound to the list of names of all the registers:
Original JavaScript
(define all-regs '(env proc val argl continue)) const all_regs = list("env", "fun", "val", "argl", "continue");
5.5.3   Compiling Combinations Applications and Return Statements