Original JavaScript
Original JavaScript
Original JavaScript

[1] Conditionals in full JavaScript accept any value, not just a boolean, as the result of evaluating the predicate expression. JavaScript's notion of truthiness and falsiness is captured by the following variants of is_truthy and is_falsy: function is_truthy(x) { return ! is_falsy(x); } function is_falsy(x) { return (is_boolean(x) && !x ) || (is_number(x) && (x === 0 || x !== x )) || (is_string(x) && x === "") || is_null(x) || is_undefined(x); } The test x !== x is not a typo; the only JavaScript value for which x !== x yields true is the value NaN (Not a Number), which is considered to be a falsy number (also not a typo), along with 0. The numerical value NaN is the result of certain arithmetic border cases such as 0 / 0.
[2] Frames are not really a data abstraction in the following code: abstraction: set-variable-value! and define-variable! use set-car! to directly modify the values in a frame. The function assign_symbol_value below uses set_head to directly modify the values in a frame. The purpose of the frame procedures functions is to make the environment-manipulation procedures functions easy to read.
[3] The drawback of this representation (as well as the variant in exercise 4.14) is that the evaluator may have to search through many frames in order to find the binding for a given variable. (Such an approach is referred to as deep binding.) One way to avoid this inefficiency is to make use of a strategy called lexical addressing, which will be discussed in section 5.5.6.
4.1.3   Evaluator Data Structures