[1] Constraint propagation first appeared in the incredibly forward-looking SKETCHPAD system of Ivan Sutherland (1963). A beautiful constraint-propagation system based on the Smalltalk language was developed by Alan Borning (1977) at Xerox Palo Alto Research Center. Sussman, Stallman, and Steele applied constraint propagation to electrical circuit analysis (Sussman and Stallman 1975; Sussman and Steele 1980). TK!Solver (Konopasek and Jayaraman 1984) is an extensive modeling environment based on constraints.
[2] The setter might not be a constraint. In our temperature example, we used user "user" as the setter.
[3] We can use the function member from section 2.3.1 to test whether new_constraint is already in constraints, although member was introduced as being limited to numbers and strings, because we extended === to pointer equality in section 3.3.1.
[4] The expression-oriented format is convenient because it avoids the need to name the intermediate expressions in a computation. Our original formulation of the constraint language is cumbersome in the same way that many languages are cumbersome when dealing with operations on compound data. For example, if we wanted to compute the product ${(a+b)}\cdot{(c+d)}$, where the variables represent vectors, we could work in imperative style, using procedures functions that set the values of designated vector arguments but do not themselves return vectors as values:
 Original JavaScript (v-sum a b temp1) (v-sum c d temp2) (v-prod temp1 temp2 answer) v_sum("a", "b", temp1); v_sum("c", "d", temp2); v_prod(temp1, temp2, answer);
Alternatively, we could deal with expressions, using procedures functions that return vectors as values, and thus avoid explicitly mentioning temp1 and temp2:
 Original JavaScript (define answer (v-prod (v-sum a b) (v-sum c d))) const answer = v_prod(v_sum("a", "b"), v_sum("c", "d"));
Since Lisp JavaScript allows us to return compound objects as values of procedures, functions, we can transform our imperative-style constraint language into an expression-oriented style as shown in this exercise. In languages that are impoverished in handling compound objects, such as Algol, Basic, and Pascal (unless one explicitly uses Pascal pointer variables), one is usually stuck with the imperative style when manipulating compound objects. Given the advantage of the expression-oriented format, one might ask if there is any reason to have implemented the system in imperative style, as we did in this section. One reason is that the non-expression-oriented constraint language provides a handle on constraint objects (e.g., the value of the adder procedure) function) as well as on connector objects. This is useful if we wish to extend the system with new operations that communicate with constraints directly rather than only indirectly via operations on connectors. Although it is easy to implement the expression-oriented style in terms of the imperative implementation, it is very difficult to do the converse.
3.3.5   Propagation of Constraints