binding maps name to value. ------- frame is a set of bindings ----- environment is a sequence of frames, linked by parent pointers, ----------- terminated by the frame for the global environment. The first frame in the sequence is called the current frame. The final frame ------------- is always the global environment, which does not have a parent ------------------ pointer. Evaluation always takes place relative to the current environment ------------------- EVALUATION RULES numbers, symbols, strings, quoted data structures ... evaluate to themselves, whatever the current environment -- same as substitution model. variables: find the binding in the environment, starting from the current frame and following parent pointers until a binding is found. Get the value from the binding. lambda: (lambda () ) form a "double bubble" pair also called a "closure" The first bubble is a pointer to the parameters of the procedure and the body of the procedure. The second bubble is a pointer to the current frame. set!: (set! ) evaluate in the current environment. Find the binding for starting from the current frame and following parent pointers until a binding is found. Replace the value in the binding. define: (define ) evaluate in the current environment. Create a binding in the current frame (or override an existing binding for the same name), binding the name to the value of the expression. (Not quite true: a bunch of defines can refer to each other in which case the behavior is more complicated.) let: (let (( ) ... ( ) Evaluate each expression in the current environment. When all expressions are evaluated: (1) create a new frame. (2) link frame to current environment (3) add all bindings of names to values of expressions into the newly-created current frame. (4) evaluate the body in the new current environment. (When done with evaluating the body, "pop" out of the created frame.) Note: we can define let in terms of lambda, combination, but that leaves a useless "double-bubble" hanging around after the let, so we give let its own rule -- as opposed to SICP on p248. combination: evaluate the expressions in any order in the current environment, then apply the value of the first (the operator) to the values of the others (the operands). applying -- a primitive procedure: same as substitution model... -- a closure (double bubble). (1) create a new frame (2) link it to the environment from the environment link of the closure. (3) create bindings, in the newly-created current frame, for all parameters of the procedure to the values of the operands. (4) evaluate the body of the closure in the new current environment. (When done with evaluating the body, return to the environment from before the application to continue computing). cond / if: -- same as substitution model.