SICP 연습문제 1.6 친절한 풀이
문제
cond를 사용해서 if식을 보통 프로시저처럼 정의할 수는 없을까?
(define (new-if predicate then-clause else-cluase) |
이 new-if는
(new-if (= 2 3) 0 5) |
위와 같은 경우에서 모두 정상작동합니다.
그렇다면 위의 new-if 프로시저를 사용해서 제곱근 프로그램에도 사용해도 되는지 확인해 보십시오.
문제로 부터 얻은 것
if식은 실행기에서 실행되는 매커니즘이 다른 프로시저들과 다릅니다. new-if 프로시저로 sqrt-iter를 구현하면, 값을 반환하지 못하고 루프에 빠집니다.
문제풀이
연습문제 1.5에서 if식이 어떻게 작동하는지를 배웠습니다. if식은 술어부predicate를 먼저 계산하고 그 결과가 참이냐 거짓이냐에 따라 참인 경우와 거짓인 경우 중 한가지만 실행합니다.
if식 대신에 new-if프로시저를 사용하게 되면, 술어부만 먼저 계산하지 않고, 인자먼저 계산법에 따라 인자들을 전부 계산한 뒤에 프로시저를 계산합니다. 다시말하면, 아래의 new-if
의 세 개의 인자를 모두 계산한 뒤에 new-if의 몸체에 있는 식들을 실행한다는 뜻입니다.
(new-if (good-enough? guess x) guess (sqrt-iter (improve guess x) x)) |
이때 Dr.Racket은 (sqrt-iter (improve guess x) x)를 계속 정의하려고 할 것이고, 끝내 정의내리지 못해서 프로세스는 무한루프에 빠질 것입니다.
이는 Dr.scheme 실행기가 if식을 다른 프로시저와는 다르게 계산하기 때문에 나타나는 현상입니다. sqrt-iter프로시저는 값을 찾을 때까지 무한 반복하다가 값을 찾으면 무한반복을 끊고 값을 반환하는 프로시저입니다. 그런데, 값을 찾았다는 것을 알기 위해서는 무한루프를 끊을 수 있는 if문이 실행되어야 합니다. 새로 만든 sqrt-iter는 if문 대신 new-if프로시저가 있기 때문에 무한루프을 끊고 값을 반환할 수 없습니다. 결론은 new-if 프로시저로 sqrt-iter를 구현하면, 값을 반환하지 못하고 무한루프에 빠진다는 것입니다.
Dr.racket에서도 종료되지 못하고 무한반복하는 모습입니다.