SICP 연습문제 1.5 친절한 풀이
문제
언어 실행기가 인자먼저 계산법을 따르는지 정의대로 계산법을 따르는지 알아보고 싶어서 아래와 같은 프로시저를 정의했다.
(define (p) (p)) |
인자먼저 계산법을 따르는 실행기라면 어떤 결과를 보게 될까? 정의대로 계산법을 따르는 실행기라면 어떤 결과를 보게 될까? 저마다 왜 그런 답이 나오는지 밝혀라
문제로 부터 얻은 것
인자먼저 계산법으로 계산했을 때 프로시저가 정상적으로 완료될 수 없는 상황도 있습니다. 인자의 계산이 끝나지 않을 수 있기 때문입니다.
문제풀이
이 문제를 풀기 위해서는 각 방법의 정의를 정확하게 알아야 합니다.
a. 인자먼저 계산법
(test 0 (p)) |
위 프로시저를 실행할 때 인자먼저 계산법대로 실행한다고 해봅시다. 인자먼저 계산법은 test 프로시저의 인자인 0과 p가 더이상 계산될 수 없을 때까지 계산한 후 반환값을 인자로 삼아서 프로시저를 실행할 것입니다. 그런데 p는 자기 자신을 계속 반환하는 함수이므로, 정상적으로 계산을 끝마칠 수 없습니다. 그러므로 test 프로시저는 p의 반환값을 영원히 받을 수 없기 때문에 완료되지 않습니다.
b. 정의대로 계산법
(test 0 (p)) |
반대로 정의대로 계산법은 위 프로시저를 우선 정의된대로 바꿉니다.
(if (= 0 0) |
그리고 문제에서 if식을 실행할 때에는 술어의 참 거짓 유무에 따라 한가지 계산식만 계산한다고 하였으므로,
(= 0 0)이 참인 시점에서 p는 실행되지 않고 test프로시저는 0을 반환합니다.
하지만 실험해 보니 현재 버전의 Dr.Racket은 인자먼저 계산법을 사용하는 것 같습니다. 프로시저가 정상종료되지 못해 유저가 직접 종료한 모습입니다.
c. 번외
그런데 기존의 코드를 아래와 같이 바꾸면 기존과는 다른 결과를 볼 수 있습니다.
;기존의 코드 |
정확한 것은 아니지만, 괄호로 묶여있는 (p)
는 프로시저를 호출하여 실행한 결과라는 의미이고, p
는 프로시저가 있는 위치만을 의미하는 것 같습니다.
읽어주셔서 감사합니다.