new-if는 코드를 보면 알 수 있듯이, if가 하는 일을 흉내내는 '함수'이고, sqrt-iter는 sqrt 함수, 즉 제곱근을 구하는 함수를 구현하기 위해 내부적으로 사용된 함수입니다.
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(define (new-if predicate then-clause else-clause)
(cond (predicate then-clause)
(else else-clause)))
(define (improve guess x)
(average guess (/ x guess)))
(define (average x y)
(/ (+ x y) 2))
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))
(define (square x)
(* x x))
(define (sqrt x)
(sqrt-iter 1.0 x))
(sqrt 2) ==> 실행 결과로 1.4 어쩌구... 의 값을 내놓습니다.
답의 힌트는 윗 단락의 밑줄 그은 부분에 있습니다. new-if로 if가 하는 일을 대체할 수 있을 것 같지만, 문제가 그리 간단치 않습니다. Scheme 함수는 함수 body를 수행하기 전에, 인자들을 전부 evaluation합니다. 그러니 new-if의 세 인자도 new-if 수행 전에 전부 evaluation되어야 합니다.
따라서, 위의 코드에서 sqrt-iter 안에서 사용된 if를 new-if로 대체하게 되면, 그 세 번째 인자로 주어진 (sqrt-iter ...) 부분을 먼저 evaluation 해야하고, 그 결과로 재귀 호출이 발생하고, new-if가 다시 호출됩니다. 그 결과로 무한루프가 발생하고, 메모리 제한 조건을 적절히 설정해 두지 않았다면 Scheme 시스템이 뻗습니다.
그런데, 이 정도의 답도 빨리 못 내어 놓는 걸 보니 제 머리가 굳긴 굳은것 같군요. -_-; 앞으로 연습문제를 좀 충실히 풀어봐야겠습니다. 굳은 머리를 풀려면...
'Books by Example > SICP' 카테고리의 다른 글
| SICP Exercise : 연습문제 1.16, 1.17, 1.18 (0) | 2007/11/15 |
|---|---|
| SICP Exercise : 연습문제 1.12 (0) | 2007/11/10 |
| SICP Exercise : 연습문제 1.11 (2) | 2007/11/10 |
| SICP Exercise : 연습문제 1.8 (8) | 2007/11/09 |
| SICP Exercise : 연습문제 1.6 (8) | 2007/11/06 |
| 컴퓨터 프로그램의 구조와 해석 : 읽기 전에 필요한 것 (8) | 2007/11/05 |
TRACKBACK http://www.buggymind.com/trackback/71
-
SCIP Exercise 연습문제 1.6 삭제
2007/12/18 12:44TRACKBACK FROM NoSyu의 주저리 주저리이 문제는 'if문을 cond를 써서 대체할 수 있지 않겠나' 하는 생각에서 출발합니다. 저의 예상은 무한루프를 돈다고 생각했습니다. 이유는 sqrt-iter 프로시저를 실행시 new-if안의 인자인 sqrt-iter를 다시금 실행시켜 연습문제 1.5와 같은 이유로 무한반복을 하리라는 예상을 했습니다. 확인을 위해 코드를 작성하고 실행시켰습니다. 예상대로 오른쪽 밑에 있는 졸라맨은 무한정 달리고 있었습니다.  ...
댓글을 달아 주세요
전 처음에 무한반복을 예상했으나
2007/12/18 10:39 [ ADDR : EDIT/ DEL : REPLY ]코드가 제대로 실행되는 것을 보고 당황했습니다.
알고보니 기존의 sqrt-iter 프로시저에 if 대신 new-if로 바꾸지 않았더군요.OTL....
그것도 모르고 '세상 참 신기하네..'라며 감탄하고 있었다니..OTL....
sqrt-iter 프로시저에서 else-clause에 있는 sqrt-iter이 재호출되기 때문이 맞죠?
메모리 제한을 걸지 않고 별 생각없이 구경하고 있다가 재부팅할 뻔했습니다.OTL.....
맞습니다. ^^
2007/12/18 13:31 [ ADDR : EDIT/ DEL ]저는 재부팅 한번 했었습니다. ㅋㅋ
아아 이런 .... OTL
2007/12/26 06:27 [ ADDR : EDIT/ DEL : REPLY ]sqrt 를 정의 하지도 않고 빌트인 sqrt 를 써서 .....
"이게 안되야하는데 왜 될까?" 하고 삽질했습니다 ㅋ
ㅋㅋㅋ 뭐 다들 그런 실수를 하죠
2007/12/26 08:59 [ ADDR : EDIT/ DEL ]디버깅 중에 good-enough?의 리턴이 참이 되는되도 guess가 아닌
2008/02/01 00:43 [ ADDR : EDIT/ DEL : REPLY ]sqrt-iter로 계속 넘어가게 되어서 생각중이었는데 답은 함수의 동작에
있었군요....ㅡㅡㅋ Scheme을 조금 더 공부해야 겠네요...^^
네. 간단하면서도 재미있는 언어인것 같습니다. :-)
2008/02/01 03:27 [ ADDR : EDIT/ DEL ]낭만고양이님의 "Scheme 함수는 함수 body를 수행하기 전에, 인자들을 전부 evaluation합니다."
2008/03/29 18:37 [ ADDR : EDIT/ DEL : REPLY ]라는 문장을 보고 순간 "아차;" 싶었습니다-_-;
scheme이 기본적으로 인자를 먼저 계산하는 메소드를 채택하고 있다는 사실을
잊어버리고 있었던채;;;
여튼, 좀 속을 끙끙 앓고 있었는데 덕분에 명쾌한 답변이 되었던것 같습니다^^
도움이 되었다니 기쁘네요.
2008/03/30 09:10 [ ADDR : EDIT/ DEL ]이 책 놓고 있은지 꽤 오래 되었는데,
다시 좀 봐야겠습니다. 책이 커서 그런지, 보는 중간에
이런 일 저런 일 참 많이 생기네요.. ㅎㅎ