이 문제는 mystery라는 이름의 프로시저를 살펴보는 문제입니다.

해당 프로시저는 loop라는 프로시저를 안에 가지고 있습니다.

이 loop 프로시저는 리스트 x의 순서를 뒤짚어 y 앞에 붙여넣는 기능이 있습니다.

따라서 y에 null을 넘겨주므로 x의 원소가 뒤짚힌 리스트가 나옵니다.

 

c6

예상대로 잘 나오는군요.^^

 

07

계산 전 v입니다.

08

계산 후 w입니다.

 

하지만 예상을 깬 것이 있습니다.

바로 계산 후 v입니다.

실행기는 계산 후 v는 (a)라고 말해줍니다.

즉, 첫 번째 원소만을 가지고 있다고 하지요.

왜 이런지 생각해보았습니다.

 

아마 이런 이유가 아닐까 싶습니다.

처음에 mystery 프로시저에 v가 들어갑니다.

그럼 loop 프로시저 첫 번째 인자로 v가 들어갑니다.

그것은 null이 아니기에 cdr을 temp에 복사한 후 set-cdr!을 당합니다.

따라서 v의 첫 번째 원소의 cdr은 y 즉, null로 바뀝니다.

그리고 temp를 첫 번째 인자로, v를 두 번째 인자로 하여 loop 프로시저를 부릅니다.

 

다시 불려진 loop는 첫 번째 인자가 null이 아니므로 역시 같은 일을 반복합니다.

여기서 set-cdr!을 당하는 것은 두 번째 인자가 아니라 첫 번째 인자입니다.

즉, 위에서 v가 아니라 temp가 set-cdr!로 cdr이 바뀌는 것입니다.

그리고 다음 번 loop를 부를 때는 y는 상관없기에 v는 더 이상 바뀌지 않습니다.

따라서 v는 한 번 set-cdr!을 당하기에 원소 (a)만 있는 것입니다.

 

다 적고나서 살펴보니 표현이 조금 이상하네요.^^;;

 

 

참조

해럴드 애빌슨, 김재우 역, <컴퓨터 프로그램의 구조와 해석>, 인사이트, 2007, pp. 333

 

 

; exercise 3.14
(define (mystery x)
  (define (loop x y)
    (if (null? x)
        y
        (let ((temp (cdr x)))
          (set-cdr! x y)
          (loop temp x))))
  (loop x '()))

; execute
(define v (list 'a 'b 'c 'd))
v
(newline)
(define w (mystery v))
v
w

크리에이티브 커먼즈 라이선스
Creative Commons License
TAG , ,

글에 잘못된 점, 다른 점, 부족한 점이 있다면 지적해주세요.
댓글, 트랙백, 메일 모두 고맙습니다.

트랙백 주소 :: http://nosyu.pe.kr/trackback/1440

댓글을 달아 주세요

[로그인][오픈아이디란?]