며칠 간 연습문제 4.3을 생각하였지만, 그 문제의 뜻을 파악하지 못했습니다. 왜냐하면 데이터 중심(data-directed) 기법을 쓰기 위해서 이차원 표를 그려야 하는데, 아무리 eval procedure를 살펴봐도 그러한 표를 그릴 수 없었기 때문입니다. 그래서 넘겨서 4.4를 보기로 하였습니다.
이 문제는 and와 or을 구현하는데, short-circuit boolean evaluation으로 만들어야 합니다. 여기에 대한 자세한 애기는 제가 적은 글을 참조해주세요. (도움은 크게 되지 않겠지만...)
거기에 맞춰서 코딩을 하였지만, and에 적혀있는 글 하나가 이해되지 않았습니다.
and : 왼쪽에서 오른쪽으로 식의 값을 구한다. 그 가운데 어떤 식이든 그 값이 거짓이면, 거짓을 내놓고 나머지 식은 계산하지 않는다. 모든 식의 값이 참이면, 마지막 식의 값을 돌려준다. 식이 아예 없으면 참이라 답한다.
- 해럴드 애빌슨, 김재우 역, <컴퓨터 프로그램의 구조와 해석>, 인사이트, 2007, pp. 488
여기서 '마지막 식의 값을 돌려준다.'라는 문구가 모호했습니다. 처음에는 문자 그대로 식의 값을 돌려준다고 생각했으나 그렇게 하려면 조금 복잡하게 만들어야 할 듯싶었습니다. 즉, T/F 여부를 확인하면서 그 값을 저장하고 있다가 True인 경우 저장한 값을 돌려주도록 만들어야 할 듯싶었습니다.
하지만 생각해보니 식들의 값은 True 아니면 False이고, 그 앞에 하나라도 거짓이면 거짓을 내놓는다고 적혀있습니다. 따라서 만약 마지막 식의 값이 False이면 False를 반환하면 되고, True라면 그 식의 값을 반환해야 하는데 그 값이 True이므로 단순히 True를 반환하면 되는 것이었습니다.
원문에는 어떻게 적혀있나 궁금해서 살펴보니 똑같이 적혀있었습니다.
and: The expressions are evaluated from left to right. If any expression evaluates to false, false is returned; any remaining expressions are not evaluated. If all the expressions evaluate to true values, the value of the last expression is returned. If there are no expressions then true is returned.
SICP 역자 중 한 분이신 안윤호님께서 참조하기 좋은 페이지를 소개해주셨습니다.
http://cparrish.sewanee.edu/cs376/schedule.html
여기서 eval 대신에 mceval이라는 것으로 가르치고 있어서 이제부터 이것을 사용하고자 합니다. 하지만 이번에는 그러하지 못했네요.^^;; 다시 한 번 안윤호님께 감사의 인사를 드립니다.
그 뒤에 적혀있는 '이끌어낸 식(derived expression)으로 and와 or를 실현하는 방법도 설명해 보라.'는 이끌어낸 식이 정확히 무엇인지 기억이 나지 않아 하지 못했습니다.ㅜ
참조
해럴드 애빌슨, 김재우 역, <컴퓨터 프로그램의 구조와 해석>, 인사이트, 2007, pp. 488
1: (load "ch4-mceval.ss") ; load mceval, http://cparrish.sewanee.edu/cs376/class16.html
2:
3: ; eval-and
4: (define (eval-and exp env)
5: (if (not (null? (and-next-exp exp))) ; 현재 식이 존재하는가?
6: (if (true? (mceval (and-now-exp exp) env)) ; 존재하니까 현재 식의 값이 참인지를 묻는다.
7: (eval-and (and-next-exp exp) env) ; Ture이기에 뒤의 식을 살펴본다.
8: 'false) ; 중간에 식의 값이 거짓이기에 거짓을 반환한다.
9: 'true) ; 마지막이거나 식이 아예 없기에 참을 반환한다. 마지막이라면 지금까지 전부 참이었기에 참을 반환해도 문제 없다.
10: )
11:
12: ; eval-and에 쓰인 것들.
13: (define (and? exp) (tagged-list? exp 'and))
14: (define (and-now-exp exp) (cadr exp))
15: (define (and-next-exp exp) (cddr exp))
16: (define (and-now-exist? exp) (not (null? (cdr exp))))
17:
18:
19: ; eval-or
20: (define (eval-or exp env)
21: (if (not (null? (or-next-exp exp))) ; 현재 식이 존재하는가?
22: (if (not (true? (mceval (or-now-exp exp) env))) ; 존재하니까 현재 식의 값이 참인지를 묻는다.
23: (eval-or (or-next-exp exp) env) ; False이기에 뒤의 식을 살펴본다.
24: 'true) ; 중간에 식의 값이 참이기에 참을 반환한다.
25: 'false) ; 마지막이거나 식이 아예 없기에 거짓을 반환한다. 마지막이라면 지금까지 전부 거짓이었기에 거짓을 반환해도 문제 없다.
26: )
27:
28: ; eval-or에 쓰인 것들.
29: (define (or? exp) (tagged-list? exp 'or))
30: (define (or-now-exp exp) (cadr exp))
31: (define (or-next-exp exp) (cddr exp))
32: (define (or-now-exist? exp) (not (null? (cdr exp))))
- SICP Exercise 연습문제 4.7 (0)2009/02/18
- SICP Exercise 연습문제 4.6 (0)2009/02/18
- SICP Exercise 연습문제 4.5 (0)2009/02/18
- SICP Exercise 연습문제 4.4 (2)2009/02/16
- SICP Exercise 연습문제 4.2 (0)2009/01/21
- SICP Exercise 연습문제 4.1 (0)2009/01/21
- SICP Quizzes (0)2008/08/04
글에 잘못된 점, 다른 점, 부족한 점이 있다면 지적해주세요.
댓글, 트랙백, 메일 모두 고맙습니다.







댓글을 달아 주세요
기존 C 프로그램에서 0이 False이지만 True는 0이 아닌 값이므로, 이를 이용한 트릭을 쓸 때에 0이 아닌 값을 반환해야 하지만 그 중에 무얼 반환해야할지 명확하지 않으므로 맨 마지막 값을 반환하는게 아닌가 싶네요. ^^
반갑습니다.
과연 그러하군요.
Lisp 혹은 여기서 만드는 언어는 과연 어떻게 해석하는지 모르겠지만, C에서처럼 0과 0이 아닌 것으로 구분한다면 마지막 값을 반환하는 것이 맞겠네요.^^
그렇다면 코드를 수정해야하는군요.OTL....
좋은 지적 고맙습니다.ㅜ