오상우
오상우

Categories

  • lisp
  • scheme
  • sicp

SW 마에스트로 멘토님의 추천으로 SICP 를 공부중이다. 책에서 사용하는 언어는 Scheme이라고 하는 Lisp의 dialect인데, 지금까지 배운 언어들과는 꽤 다르지만 재밌는 언어다.

연습문제 1.34

크게 어려울 건 없는 문제로, 인자로 프로시저를 받아서 그 프로시저에 2를 인자로 주어 실행하는 프로시저에 자기 자신을 인자로 주면 (음,,, 말이 좀 길긴 한데 맞는 말이다) 아래와 같이 진행되어 에러가 발생함을 보이면 된다.

(define (f g)
  (g 2))

(f f)

(f 2)

(2 2)

; 에러 발생!

연습문제 1.41

프로시저를 인자로 받아, 그 프로시저를 연거푸 계산하는 프로시저 double 이 있을 때,
아래 식의 값을 구하는 문제이다.

(((double (double double)) inc) 5)

식을 하나하나 풀어 대입해보면 inc 를 16번 되풀이해 계산하므로 정답은 21이 된다.

연습문제 1.42

두 프로시저 g 와 f를 합성한 프로시저를 리턴하는 프로시저 compose를 정의하라.

(define (compose f g)
  (lambda (x) (f (g x))))

(define (inc n)
  (+ n 1))

((compose square inc) 6)
; 42

연습문제 1.43

위의 compose 프로시저를 활용하여 주어진 프로시저 f 를 n번 적용하는 프로시저를 리턴하는 repeated 프로시저를 정의하라.

(define (repeated-iter cur-f f n count)
  (if (= count n)
      (lambda (p) (cur-f p))
      (repeated-iter (compose f cur-f) f n (+ count 1))))

(define (repeated f n)
  (repeated-iter f f n 1))

((repeated square 2) 5)

반복 프로시저를 사용하여 위와 같이 구현해 보았다.

연습문제 1.44

위에서 정의한 repeated 함수를 이용해 어떤 함수를 n-번 smooth 한 함수를 돌려주는 프로시저 repeated-smooth를 정의하는 문제이다.

(define (avg x y z) (/ (+ x y z) 3))

(define (smooth f)
  (lambda (x)
    (let ((dx 0.001))
      (avg (f (+ x dx)) (f x) (f (- x dx))))))

(define (repeated-smooth f n)
  (lambda (p) ((repeated (smooth f) n) p)))

((repeated-smooth square 2) 3)

연습문제 1.46

반복하여 고치기(iterative improvement)라고 하는 일반적 계산법을 프로시저로 정의해보자.
iterative improvement는 특정 값을 구할 때, 어떤 값에서 시작해 그 값이 특정 범위 안에 들어 올 때까지 반복해서 improve하는 형태의
프로시저를 의미한다.

(define (iter-improve enough? improve)
  (define (iter p)
    (if (enough? p)
        p
        (iter (improve p))))
  (lambda (p) (iter p)))