SICP 연습문제 1.32 친절한 풀이

문제

a. 아래처럼 a에서 b사이에 있는 어떤 수열을 묶어 가는 개념, 곧 accumulate가 있다고 할때, sum과 연습문제 1.31에서 만든 product가 이 개념을 응용한 보기 가운데 하나임을 밝혀라.

(accumulate combiner null-value term a next b)

accumulate는 이어지는 두 값을 묶는 프로시저 combiner와, 계산할 값이 없을 때 쓰는 null-value인자를 받는다. 나머지 인자는 sum이나 product에서 쓰는 인자(term,a,next,b)와 같다. accumulate를 만든 다음에 sum과 product를 accumulate를 불러 쓰는 프로시저로 짜 보라.

b. accumulate의 프로세스가 되돈다면 반복하도록 고쳐 쓰고, 그 반대로 반복한다면 되돌도록 고쳐 보라.

문제로 부터 얻은 것

구조가 비슷한 프로시저들은 차수가 더욱 높은 프로시저로 요약함으로써 표현력을 극대화할 수 있습니다.

문제풀이

a. accumulate로 sum과 product 짜기

앞의 예제들에서 만든 sum과 product 프로시저를 한번 비교해 보겠습니다.





sum 프로시저

(define (sum term a next b)
(define (iter a result)
(if (> a b)
result
(iter (next a) (+ result (term a)))))
(iter a 0))

product 프로시저

(define (product term a next b)
(define (iter a result)
(if (> a b)
result
(iter (next a) (* result (term a)))))
(iter a 1))





두 프로시저의 차이는 두가지 밖에 없습니다.

  1. result에 값을 축적하는 방식이 +와 *로 다르다.
  2. result의 초기값이 0과 1로 다르다.





위의 두가지 요소는 각각 accumulate 프로시저의 인자인 combiner와 null-value로 추상화할 수 있습니다.
이런 아이디어로 accumulate 프로시저를 짜보면 다음과 같습니다.

(define (accumulate combiner null-value term a next b)
(define (iter a result)
(if (> a b)
result
(iter (next a) (combiner result (term a)))))
(iter a null-value))





위의 두 프로시저와 크게 다른 것이 없음을 알 수 있습니다.

accumulate로 product와 sum을 구현하면 다음과 같습니다.

(define (sum term a next b)
(accumulate + 0 term a next b))

(define (product term a next b)
(accumulate * 1 term a next b))

b. accumulate를 되도는 프로세스가 되도록 짜기

기본의 반복하는 프로세스는 result에 값을 축적했습니다.
되도는 프로세스는 result없이 combiner로 (term a)의 값을 묶어주기만 하면 됩니다.

(define (accumulate combiner null-value term a next b)
(define (iter a)
(if (> a b)
null-value
(combiner (iter (next a))
(term a))))
(iter a))





읽어주셔서 감사합니다.