Rules of evaluation The value of a number is itself. The value of a Boolean is itself. The value of a symbol is the data object it is bound to. The value of a list is obtained as follows: First evaluate each item in the list. The first item should evaluate to a procedure. Apply the procedure to the values of the rest of the items. The result of the procedure application is the value of the list. Something is missing… Lambda expressions! (lambda (x) (+ 1 x) They don’t fit the list rule: lambda is not an procedure. Even if it were, the other items in the list are not evaluated.
Special forms Some lists are evaluated … in a special way. Which lists? How can you tell? We say a list is a special form if the first item of the list is one of the following symbols: lambda quote cond if and or For each of these symbols, we will have a special rule. Special forms are considered expressions, so we have to amend our definition of expressions too.
lambda special rule: The value of the list is a procedure whose arg list is the second item in the list, and whose body is the third item in the list.
The value of a number is itself. The value of a Boolean is itself. The value of a symbol is the data object it is bound to. The value of a list is obtained as follows: First evaluate each item in the list. The first item should evaluate to a procedure. Apply the procedure to the values of the rest of the items. The result of the procedure application is the value of the list. lambda special rule: The value of the list is a procedure whose arg list is the second item in the list, and whose body is the third item in the list. Quiz: What are the values of the following expressions? ((lambda (x) (+ x 2)) ((lambda (y) (* y 2)) 3)) ((lambda (f) (f 3 2)) +)
Your next special form: The quote form We mostly use symbols as variables, but sometimes we will use them as data objects within a program. This poses a problem: How can we get our hands on a symbol in the code? In particular, we need an expression whose value is the symbol. Say you want an expression to check if variable x is bound to the symbol rainy. (equal? x rainy) Nope. According to the rules of evaluation, this will test equality between the data objects x and rainy are bound to. How to keep the voracious evalpig from trying to eat the symbol? Need a protective sheath: that’s what a quote form is. (equal? x (quote rainy))
The quote form rule The value of a list whose first item is the symbol quote is the second item. evaluation (quote rainy) rainy (quote (rainy cold)) (rainy cold) (quote (+ rainy cold)) (+ rainy cold) (quote (+ 2 3)) (+ 2 3) Lesson: Just because something looks like an expression doesn’t mean it will get evaluated. Conversely: Just because something doesn’t look like an expression doesn’t mean it won’t get evaluated.
The last special form you’ll ever need: cond ((= x 10) 1) ((= x 20) 2) ((= x 30) 3) ) If x = 10, the value is 1. If x = 20, the value is 2. If x = 30, the value is 3. If x is none of those, the value is … BLARGH! (error) (cond ((equal? x (quote rainy)) (+ 2 5)) ((equal? x (quote cold)) (/ (+ 3 7) 2)) ((equal? x (quote hot)) (/ (+ 3 7) 0)) )
The cond rule: To evaluate a list whose first item is cond, Each of the remaining items (2, 3, …n) must be a two-element list. Evaluate the first element of item 2; the value must be a Boolean. If it is true, the value of the cond is the value of the second element. Evaluate the first element of item 3; the value must be a Boolean. If it is true, the value of the bond is the value of the second element. Evaluate the first element of item 4; the value must be a Boolean. If it is true, the value of the bond is the value of the second element. …. Evaluate the first element of item n; the value must be a Boolean. If it is true, the value of the bond is the value of the second element. (cond ((equal? x (quote rainy)) (+ 2 5)) ((equal? x (quote cold)) (/ (+ 3 7) 2)) ((equal? x (quote hot)) (/ (+ 3 7) 0)) )
(cond ((equal? x (quote rainy)) (+ 2 5)) ((equal? x (quote cold)) (/ (+ 3 7) 2)) ((equal? x (quote hot)) (/ (+ 3 7) 0)) ) The cond rule: To evaluate a list whose first item is cond, Each of the other items must be a two-element list: (question answer) Both elements must be expressions; question must be Boolean-valued. The value of the cond is the value of the answer corresponding to the first question whose value is true. Key point: the later question and answer expressions are not evaluated. (cond (true 3) ((= x 1) (/ 1 0)))
Example of cond If none of the question expressions evaluates to true, BLARGH! Often last question is just true. (cond ((> temp 80) (quote hot)) ((< temp 60) (quote cold)) (true (quote moderate)) )
We don’t need any more special forms… … but we will give two more. (and expr-1 expr-2 … expr-n) (or expr-1 expr-2 … expr-n) These are Boolean operations: the inputs are Boolean and the output is Boolean. and x y true false Or x y true false and is true if all its expressions evaluate to true, else false. or is false if all its expressions evaluate to false, else true.
The and and or special forms (and expr-1 expr-2 … expr-n) (or expr-1 expr-2 … expr-n) and is true if all its expressions evaluate to true, else false. or is false if all its expressions evaluate to false, else true. What makes them special? Just enough expressions are evaluated to decide the answer—and no more. (and (= 1 1) (= 2 0) (= 5 (/ 1 0))) successfully evaluates to false. We call this short-circuiting: evaluate expressions in order, but stop when you know the answer.