생각해 볼 질문
평가기가 if의 두 가지를 모두 평가하면 무엇이 잘못될까요?
- 자신만의 평가 규칙을 가진 문법 알아보기
- 갈래를 선택하기 전에 술어 먼저 평가하기
- 선택되지 않은 식이 아무 일도 하지 않음을 관찰하기
if 경우는 먼저 술어만 평가합니다. 그런 다음 귀결이나 대안 중 하나에 대해서만 evaluate를 호출하며 결코 둘 다 호출하지 않습니다.
첫 번째 예제에서 대안은 0으로 나눕니다. 참인 술어가 덧셈 갈래를 선택하고 유효하지 않은 대안은 식 데이터로 남아 있으므로 프로그램은 여전히 60을 반환합니다.
SICP 코드UTF-8 975 / 1,048,576바이트
(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))))
예제
예상 결과첫 프로그램은 0으로 나누는 식을 평가하지 않고 60을 반환합니다.
실행 추적에서 볼 점보다 작음 비교가 참을 반환한 뒤 덧셈 갈래로 들어가는 평가 과정을 따라가세요. 이번 실행에는 나눗셈 적용이 나타나지 않습니다.
직접 해보기프로그램을 수정하고 결과를 비교해 보세요.
score를 70으로 바꾸고 대안을 score로 교체하세요. evaluate가 어느 갈래를 방문할지 예상하세요.
힌트 보기
evaluate 안의 호스트 if는 해석되는 if의 평가 규칙을 강제합니다.