오상우
오상우

Categories

  • lisp
  • scheme
  • sicp

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

연습문제 2.4

lisp에 원래 존재하는 cons, car, cdr를 프로시저만을 이용해서 구현할 수 있다.

(define (cons x y)
  (lambda (m) (m x y)))

(define (car z)
  (z (lambda (p q) p)))

(define (cdr z)
  (z (lambda (p q) q)))

이때 cons를 통해 생성된 pair는 실제로 프로시저이다(물론 실제 lisp에서 pair를 프로시저로 구현하진 않았다).

연습문제 2.5

수와 산술 연산만을 이용해 양의 정수 pair 데이터를 구현해 보는 문제. 양의 정수 a, b 쌍을 2^a * 3^b로 나타낼 때, 알맞은 cons, car, cdr를 정의하면 된다.

(define (iter-square a cur n)
  (if (= n 1)
      a
      (iter-square (* a cur) cur (- n 1))))

(define (cons a b)
  (* (iter-square 2 2 a) (iter-square 3 3 b)))

(define (n-in n target count)
  (if (< 0 (remainder target n))
      count
      (n-in n (/ target n) (+ count 1))))

(define (car z)
  (n-in 2 z 0))

(define (cdr z)
  (n-in 3 z 0))

; 테스트
(define pair (cons 5 7))
(car pair)
(cdr pair)

이 문제를 풀면서 느낀 것은 정말 데이터를 프로시저로 구현하는 것이 논리적으로만 맞다면 내부적으로 어떻게 되던 상관이 없다는 점이었다.

연습문제 2.6

정수 0과, 정수에 1을 더하는 연산을 수가 아닌 프로시저만으로 다음과 같이 구현할 수 있다.

; 인자 f를 한번도 apply 하지 않았으므로 0
(define zero 
  (lambda (f)
    (lambda (x) x)))

; 인자 n에 f, x를 차레로 주고 그 결과값을 f에 한번 apply 하므로 + 1
(define (add-1 n)
  (lambda (f)
    (lambda (x)
      (f ((n f) x)))))

(define one 
  (lambda (f)
    (lambda (x)
      (f x))))

(define two
  (lambda (f)
    (lambda (x)
      (f (f x)))))

; 두 0이상의 정수를 더하는 프로시저
(define (+ a b)
  (lambda (f)
    (lambda (X)
      ((b f) ((a f) x)))))