이 문제는 리스트의 내용을 변형할 수 있는 set-car!과 set-cdr!을 이용하여

2.2.1절에 나온 리스트를 연결하는 append 프로시저와 같은 일을 하는

append! 프로시저를 살펴보는 문제입니다.

 

c2

첫 번째 답은 (b), 두 번째 답은 (b c d)입니다.

왜냐하면 x의 cdr은 car이 b, cdr이 null인 리스트를 가리킵니다.

 

그리고 (append! x y)로 두 리스트를 묶은 것을 w라 하였습니다.

하지만 append!를 하였기에 (cdr x)의 cdr은 null이 아니라 y가 됩니다.

따라서 (cdr x)를 출력하면 (b c d)가 나오는 것입니다.

 

 

상자와 화살표 그림으로 이렇게 됩니다.

01

x와 y는 각각 a b, c d를 담고 있습니다.

여기서 (append x y)를 하여 이를 z라 하면 다음과 같습니다.

02

즉, x와 y를 이어붙인 리스트가 되는 것입니다.

 

역시 (append! x y)를 하여 이를 w라 한다면 다음과 같습니다.

03

이 역시 x와 y를 붙인 리스트가 되는 것입니다.

 

하지만 위의 두 프로시저는 분명 차이가 있습니다.

바로 x의 끝 원소를 바꾸는 것입니다.

append! 프로시저는 x의 끝의 null을 y를 가리키는 대상을 가리킵니다.

04

그렇게 한 것을 w라 하였기에 w는 위에서처럼 나오는 것입니다.

 

 

처음에 append 프로시저를 만들 때 저와 같은 방법을 생각했습니다.

왜냐하면 리스트 원소들의 cdr은 다음 원소들의 리스트를 지정하는 것이기에

마지막 것만 바꾸면 된다고 생각했습니다.

하지만 바꾸게 되면 그 원본도 바뀌게 되니 골이 아프네요.^^;;

결과를 만든 후에 다시 처음으로 돌리거나

call by value 방식의 프로시저를 찾아봐야겠습니다.^^

(그러고보니 이건 call by reference인 듯...)

 

 

참조

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

 

 

(define (append x y)
  (if (null? x)
      y
      (cons (car x) (append (cdr x) y))))

(define (append! x y)
  (set-cdr! (last-pair x) y)
  x)

(define (last-pair x)
  (if (null? (cdr x))
      x
      (last-pair (cdr x))))

(define x (list 'a 'b))
(define y (list 'c 'd))
(define z (append  x y))
z
(cdr x)

(define w (append! x y))
w
(cdr x)

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

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

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

댓글을 달아 주세요

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