A special form chooses what gets evaluated.
An evaluator cannot treat if like an ordinary procedure because it must select one branch before evaluating that branch.
What would go wrong if an evaluator evaluated both branches of if?
- Recognize syntax with its own evaluation rule
- Evaluate the predicate before selecting a branch
- Observe that an unselected expression performs no work
The if case first evaluates only the predicate. It then calls evaluate on either the consequent or the alternative, never both.
In the first example the alternative divides by zero. The program still returns 60 because the true predicate selects the addition branch and the invalid alternative remains expression data.
(begin
(define (lookup name environment)
(cdr (assoc name environment)))
(define (evaluate expression environment)
(cond ((number? expression) expression)
((symbol? expression) (lookup expression environment))
((eq? (car expression) 'if)
(if (evaluate (cadr expression) environment)
(evaluate (caddr expression) environment)
(evaluate (cadddr expression) environment)))
((eq? (car expression) '<)
(< (evaluate (cadr expression) environment)
(evaluate (caddr expression) environment)))
((eq? (car expression) '+)
(+ (evaluate (cadr expression) environment)
(evaluate (caddr expression) environment)))
((eq? (car expression) '/)
(/ (evaluate (cadr expression) environment)
(evaluate (caddr expression) environment)))))
(evaluate '(if (< score 60) (+ score 5) (/ 1 0))
'((score . 55))))- Output
- —
- Value
- —
- Diagnostic
- —
The first program returns 60 without evaluating the division by zero.
After the less-than comparison returns true, follow evaluation into the addition branch. No division application appears in this run.
Change the program before you read the hint.
Change score to 70 and replace the alternative with score. Predict which branch evaluate will visit.
Show one hint
The host if inside evaluate enforces the evaluation rule of the interpreted if.