Books by Example/SICP2007.11.06 00:38
예전같으면 거뜬히 풀었을것도 같은데 (정말?) 이제 답 근처까지 가는건 가능해도 정답을 맞추는게 잘 안되네요. 문제는 이렇습니다. 다음의 소스 코드를 보면 sqrt-iter를 정의하면서 if를 사용한 부분이 있는데, 이 if 대신 new-if (이 함수의 정의도 소스 코드에 포함되어 있습니다)를 사용하면 어떻게 되느냐는 겁니다.

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 시스템이 뻗습니다.


아 진땀

아 역시 그런거였나?



그런데, 이 정도의 답도 빨리 못 내어 놓는 걸 보니 제 머리가 굳긴 굳은것 같군요. -_-; 앞으로 연습문제를 좀 충실히 풀어봐야겠습니다. 굳은 머리를 풀려면...


신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

  1. 전 처음에 무한반복을 예상했으나
    코드가 제대로 실행되는 것을 보고 당황했습니다.
    알고보니 기존의 sqrt-iter 프로시저에 if 대신 new-if로 바꾸지 않았더군요.OTL....
    그것도 모르고 '세상 참 신기하네..'라며 감탄하고 있었다니..OTL....

    sqrt-iter 프로시저에서 else-clause에 있는 sqrt-iter이 재호출되기 때문이 맞죠?
    메모리 제한을 걸지 않고 별 생각없이 구경하고 있다가 재부팅할 뻔했습니다.OTL.....

    2007.12.18 10:39 신고 [ ADDR : EDIT/ DEL : REPLY ]
  2. 아아 이런 .... OTL

    sqrt 를 정의 하지도 않고 빌트인 sqrt 를 써서 .....

    "이게 안되야하는데 왜 될까?" 하고 삽질했습니다 ㅋ

    2007.12.26 06:27 신고 [ ADDR : EDIT/ DEL : REPLY ]
  3. 디버깅 중에 good-enough?의 리턴이 참이 되는되도 guess가 아닌
    sqrt-iter로 계속 넘어가게 되어서 생각중이었는데 답은 함수의 동작에
    있었군요....ㅡㅡㅋ Scheme을 조금 더 공부해야 겠네요...^^

    2008.02.01 00:43 신고 [ ADDR : EDIT/ DEL : REPLY ]
  4. 낭만고양이님의 "Scheme 함수는 함수 body를 수행하기 전에, 인자들을 전부 evaluation합니다."
    라는 문장을 보고 순간 "아차;" 싶었습니다-_-;
    scheme이 기본적으로 인자를 먼저 계산하는 메소드를 채택하고 있다는 사실을
    잊어버리고 있었던채;;;
    여튼, 좀 속을 끙끙 앓고 있었는데 덕분에 명쾌한 답변이 되었던것 같습니다^^

    2008.03.29 18:37 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • 도움이 되었다니 기쁘네요.
      이 책 놓고 있은지 꽤 오래 되었는데,
      다시 좀 봐야겠습니다. 책이 커서 그런지, 보는 중간에
      이런 일 저런 일 참 많이 생기네요.. ㅎㅎ

      2008.03.30 09:10 신고 [ ADDR : EDIT/ DEL ]