특수 형식은 무엇을 평가할지 고른다.
if는 어느 가지를 평가할지 먼저 정해야 하므로 보통 프로시저처럼 다룰 수 없습니다.
생각해 볼 질문
평가기가 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))))리스펙스 학습용 런타임리스펙스 SICP 프로필 1.0.0
리스펙스 SICP 런타임 불러오는 중
리스펙스 · SICP 코드UTF-8 975 / 1,048,576바이트
예제
결과—
- 출력
- —
- 값
- —
- 진단
- —
보이는 실행 흐름0 / 0 개의 실행 이벤트
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 score to 70 and replace the alternative with score. Predict which branch evaluate will visit.
힌트 하나 보기
The host if inside evaluate enforces the evaluation rule of the interpreted if.