sicp ch2 5 - andstudy/forge GitHub Wiki
- 2.1 ๋ฐ์ดํฐ์์ฝ
- ํ๋ก์์ ๋ฅผ ์ด๋ป๊ฒ ์งฐ๋์ง ๋ชจ๋ฅด๋๋ผ๋ ๊ฐ์ ์ผ์ ํ๊ธฐ๋ง ํ๋ค๋ฉด, ์๋ก ๋ฌ๋ฆฌ ๋ง๋ ํ๋ก์์ ๋ฅผ ๋ง๋ฐ๊ฟ ์ธ ์ ์๋ค.
- 2.4 ์์ฝ๋ ๋ฐ์ดํฐ์ ํํ์ด ์ฌ๋ฌ ๊ฐ์ง์ผ ๋
- ์ฌ๋ฌ ํํ ๋ฐฉ์๊ณผ ๊ทธ์ ๋ฐ๋ฅธ ๋ฐ์ดํฐ ์ฐ์ฐ ์ฝ๋๋ฅผ ์๋ก ์ฐ๊ฒฐํ๊ธฐ ์ํด ์ผ๋ฐํ๋ ์ฐ์ฐ์ ์ ์ํด ์ฌ์ฉ
- ๋ฐ์ดํฐ ์ค์ฌ ํ๋ก๊ทธ๋๋ฐ
- ๋ฉ์์ง ํจ์ฑ
- ์ฌ๋ฌ ํํ ๋ฐฉ์๊ณผ ๊ทธ์ ๋ฐ๋ฅธ ๋ฐ์ดํฐ ์ฐ์ฐ ์ฝ๋๋ฅผ ์๋ก ์ฐ๊ฒฐํ๊ธฐ ์ํด ์ผ๋ฐํ๋ ์ฐ์ฐ์ ์ ์ํด ์ฌ์ฉ
- ๋ฐ์ดํฐ ์ค์ฌ ๊ธฐ๋ฒ์ ๋ฐํ์ผ๋ก ์ง๊ธ๊น์ง ๋ง๋ ์ฐ์ ์ฐ์ฐ ๊พธ๋ฌ๋ฏธ๋ฅผ ๋ชจ๋ ํฉ์ณ์, ํ ๋ฉ์ด๋ฆฌ ์ฐ์ ์ฐ์ฐ ๊พธ๋ฌ๋ฏธ๋ก ์ง ๋ง์ถ์
-
์ผ๋ฐํ๋ ํ๋ก์์ ๊ฐ ์ธ์์ ํ์ ์ ๋ฐ๋ผ ์๋ง์ ๊พธ๋ฌ๋ฏธ๋ก ์ผ์ ๋๊ธฐ๊ฒ ๋ง๋ ๋ค
-
์) ์ผ๋ฐ์, ์ ๋ฆฌ์, ๋ณต์์๋ฅผ ๋ํ๋ add ํ๋ก์์
;; ์ผ๋ฐ์ (add (make-scheme-number 10) (make-scheme-number 5)) ;; ์ ๋ฆฌ์ (add (make-rational 1 5) (make-rational 1 10)) ;; ๋ณต์์ (add (make-complex-from-real-imag 3 4) (make-complex-from-real-imag 1 2))
-
-
2.4์ฅ์ ์ผ๋ฐํ๋ ๊ณ ๋ฅด๊ฐ ์ฐ์ฐ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฐ์ดํฐ์ค์ฌํ๋ก๊ทธ๋๋ฐ์ ํตํด ๊ตฌํ ํ ์ ์๋ค.
; 2.4์ฅ์์ ๊ตฌํํ ์ผ๋ฐํ๋ ๊ณ ๋ฅด๊ฐ์ฐ์ฐ (define (real-part_ z) (apply-generic 'real-part_ z)) ; ์ง๊ต์ขํ ๊พธ๋ฌ๋ฏธ ;; ๊ฐํ ํ๋ก์์ (define (real-part_ z) (car z)) ;; ์ธํฐํ์ด์ค (put 'real-part_ '(rectangular) real-part_) ; ๊ทน์ขํ ๊พธ๋ฌ๋ฏธ ;; ๊ฐํ ํ๋ก์์ (define (real-part_ z) (* (magnitude_ z) (cos (angle_ z)))) ;; ์ธํฐํ์ด์ค (put 'real-part_ '(polar) real-part_) -
์ผ๋ฐํ๋ ์ฐ์ ์ฐ์ฐ ๊ตฌํ
; ์ผ๋ฐํ๋ ์ฐ์ ์ฐ์ฐ (define (add x y) (apply-generic 'add x y)) (define (sub x y) (apply-generic 'sub x y)) (define (mul x y) (apply-generic 'mul x y)) (define (div x y) (apply-generic 'div x y)) -
์ผ๋ฐ์, ์ ๋ฆฌ์, ๋ณต์์ ๊พธ๋ฌ๋ฏธ์์ add, sub, mul, div์ ์ธํฐํ์ด์ค์ ๊ฐํ ํ๋ก์์ ๋ฅผ ์ ์ํ๋ฉด ๋๋ค.
-
3+4i๋ฅผ ์ง๊ต์ขํ๋ก ํํํ๋ฉด ์๋์ ๊ฐ์ ํ๋๋ก ์ ์ฅ๋์ด์๋ค
- ('complex . ('rectangular . (3 . 4)))
-
real-part ํธ์ถ์ ํ๋ก์์ ๊ฐ ์ ์ฉ๋๋ ์์
- ์ผ๋ฐํ๋ real-part
- apply-generic
- complex ๊พธ๋ฌ๋ฏธ์ real-part
- apply-generic
- rectangular ๊พธ๋ฌ๋ฏธ์ real-part
- ์ผ๋ฐํ๋ real-part
-
๋ฐ์ดํฐ์ ๋ณํ
- ์ผ๋ฐํ๋ real-part ์ธ์
- ('complex . ('rectangular . (3 . 4)))
- complex ๊พธ๋ฌ๋ฏธ์ real-part ์ธ์
- ('rectangular . (3 . 4))
- rectangular ๊พธ๋ฌ๋ฏธ์ real-part ์ธ์
- (3 . 4)
- ๊ฒฐ๊ณผ
- 3
- ์ผ๋ฐํ๋ real-part ์ธ์
-
scheme-number ๋์ ๊ธฐ๋ณธ์๋ฅผ ์ฌ์ฉํ๋๋ก ํด์ผ ํ๋ค.
-
ํ๊ทธ๊ฐ ์๋ ๊ธฐ๋ณธ์์ผ ๊ฒฝ์ฐ 'scheme-number์ ํ๊ทธ๊ฐ ์๋ ๊ฒ์ผ๋ก ์ฒ๋ฆฌ
(define (type-tag datum) (cond ((pair? datum) (car datum)) ((number? datum) 'scheme-number) (else (display (list "Bad tagged datum -- TYPE-TAG" datum))))) (define (contents datum) (cond ((pair? datum) (cdr datum)) ((number? datum) datum) (else (display (list "Bad tagged datum -- CONTENTS" datum))))) (define (install-scheme-number-package) (put 'add '(scheme-number scheme-number) (lambda (x y) (+ x y))) (put 'sub '(scheme-number scheme-number) (lambda (x y) (- x y))) (put 'mul '(scheme-number scheme-number) (lambda (x y) (* x y))) (put 'div '(scheme-number scheme-number) (lambda (x y) (/ x y))) 'done)
; ์ผ๋ฐํ๋ ์ฐ์ฐ
(define (equ? x y) (apply-generic 'equ? x y))
(define (install-scheme-number-package)
...
(put 'equ? '(scheme-number scheme-number)
(lambda (x y) (= x y)))
(define (install-rational-package)
...
(put 'equ? '(rational rational)
(lambda (x y) (and (= (numer x) (numer y))
(= (denom x) (denom y)))))
(define (install-complex-package)
...
(put 'equ? '(complex complex)
(lambda (z1 z2) (and (= (real-part_ z1) (real-part_ z2))
(= (imag-part_ z1) (imag-part_ z2)))))
; ์ผ๋ฐํ๋ ์ฐ์ฐ
(define (=zero? x) (apply-generic '=zero? x))
(define (install-scheme-number-package)
...
(put '=zero? '(scheme-number)
(lambda (x) (= x 0)))
(define (install-rational-package)
...
(put '=zero? '(rational)
(lambda (x) (= 0 (numer x))))
(define (install-complex-package)
...
(put '=zero? '(complex) =zero?)
(define (install-rectangular-package)
...
(put '=zero? '(rectangular)
(lambda (z) (and (= 0 (real-part_ z))
(= 0 (imag-part_ z)))))
(define (install-polar-package)
...
(put '=zero? '(polar)
(lambda (x) (= 0 (magnitude_ x))))
'done)
- ์ง๊ธ๊น์ง ์ ์ํ ์ฐ์ฐ์ ๊ผด์ด ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฅผ ์๋ก ์์ ํ ๋
๋ฆฝ๋ ๋ฐ์ดํฐ๋ก ๋ฐ์๋ค์ด๊ณ ์๋ค.
- ์ง๊ธ๊น์ง๋ ๋ฐ์ดํฐ ํ์ ์ ๊ฒฝ๊ณ๋ฅผ ๊ฐ๋ก์ง๋ฅด๋ ์ฐ์ฐ์ด ์๋ค.
-
์๋ก ๋ค๋ฅธ ํ์ ์ฌ์ด์์ ์ผ์ด๋ ์ ์๋ ์ฐ์ฐ๋ง๋ค ๊ทธ์ ํด๋นํ๋ ํ๋ก์์ ๋ฅผ ํ๋์ฉ ์ค๊ณ
(define (install-complex-package) ... ; ๊ฐํ ํ๋ก์์ (define (add-complex-to-schemenum z x) (make-from-real-imag (+ (real-part_ z) x) (imag-part_ z))) ; ์ธํฐํ์ด์ค (put 'add '(complex scheme-number) (lambda (z x) (tag (add-complex-to-schemenum z x)))) -
๋ฌธ์ ์
- ๋ฒ๊ฑฐ๋กญ๋ค
- ๋ง๋ถ์ด๋ฏ ์ฎ์ด ์ฐ๋๋ฐ ๋ฐฉํด ๋๋ค
-
๋ฐ์ดํฐ ํ์ ์ด ์๋ก ์์ ํ ๋ ๋ฆฝ๋์ง ์์์ ๋ ์ฌ์ฉ ๊ฐ๋ฅ
-
ex) ๋ณต์์์ ์ผ๋ฐ์์ ์ฐ์ ์ฐ์ฐ ์ ์ผ๋ฐ์๋ฅผ ํ์๋ถ๊ฐ 0์ธ ๋ณต์์๋ก ์ฒ๋ฆฌ
(define (scheme-number->complex n) (make-complex-from-real-imag (contents n) 0)) (put-coercion 'scheme-number 'complex scheme-number->complex)
-
-
๋ฐ์ดํฐ ํ์ ๋ฐ๊ฟํ๋ฅผ ๋ง๋ ๋ค
-
apply-generic ํ๋ก์์ ๋ฅผ ๊ณ ์ณ์ผ ํ๋ค.
-
์ฐ์ฐ์ด ์ธ์ํ์ ์ ๋ง๊ฒ ์ ์ ๋์ด์์ง ์์๋ ํ์ ๋ฐ๊พธ๊ธฐ๋ฅผ ์๋ํ๋ค
(define (apply-generic op . args) (let ((type-tags (map type-tag args))) (let ((proc (get op type-tags))) (if proc (apply proc (map contents args)) (if (= (length args) 2) (let ((type1 (car type-tags)) (type2 (cadr type-tags)) (a1 (car args)) (a2 (cadr args))) (let ((t1->t2 (get-coercion type1 type2)) (t2->t1 (get-coercion type2 type1))) (cond (t1->t2 (apply-generic op (t1->t2 a1) a2)) (t2->t1 (apply-generic op a1 (t2->t1 a2))) (else (error "No method for these types" (list op type-tags)))))) (error "No method for these types" (list op type-tags)))))))
-
-
์ฅ์
- ํ์
ํ ์์ ํ๋ก์์ ํ๋์ฉ๋ง ์ ์ํ๋ฉด ๋๋ค
- ์๋ถ์ด๊ธฐ ์ฐ์ฐ์ ์ด์ฉํ๋ฉด ๋ฐ์ดํฐ ํ์ ์ด n๊ฐ ์ผ ๋ ์ต๋ n^2๊ฐ์ ํ๋ก์ง์๊ฐ ํ์
- ํ์
ํ ์์ ํ๋ก์์ ํ๋์ฉ๋ง ์ ์ํ๋ฉด ๋๋ค
-
์์ ๊ฐ์ด ๊ตฌํ ํ์๋์ ํ๊ณ
- ๋ ๋ฌผ์ฒด ์ฌ์ด์์ ์๋ก ์ด๋ ์ชฝ ํ์ ์ผ๋ก๋ ๋ฐ๊ฟ ๋ฐฉ๋ฒ์ด ์์ง๋ง ๋ ๋ฌผ์ฒด๋ฅผ ์์ ๋ค๋ฅธ ํ์ ์ผ๋ก ๋ฐ๊พธ๋ฉด ๋ฐ๋ผ๋ ์ฐ์ฐ์ด ๊ฐ๋ฅํ ์ ์๋ ๊ฒฝ์ฐ๊ฐ ์๋ค.
- ํ
- ๋ฐ์ดํฐ ํ์ ๋ง๋ค ๊ทธ ์ ํ์ ์ด๋ ์๋ ํ์ ์ด ๋ง์์ผ ํ๋์ธ ๊ณ์ธต ๊ด๊ณ
- ์ฅ์
- ์ ํ์ ๊ณผ ์๋ ํ์ ๋ง ๋ฐํ๋ฉด ๋๋ค.
- ์๋ก์ด ๋ฐ์ดํฐ ํ์ ์ ์ง์ด ๋ฃ๊ธฐ ์ฝ๋ค.
- ๋ฌผ๋ ค ๋ฐ๋ ๊ฐ๋ ์ ์ฝ๊ฒ ๊ตฌํ ๊ฐ๋ฅ
- ๋์ด ๋ด๋ฆฌ๊ธฐ ์ฝ๋ค.
- ํ ๋ฐ์ดํฐ ํ์ ์ ์๋ ํ์ ์ด ์ฌ๋ฟ ์์ ๊ฒฝ์ฐ
- ํ ๋ฐ์ดํฐ ํ์ ์ ์ ํ์ ์ด ์ฌ๋ฟ ์์ ๊ฒฝ์ฐ
- ๋ชจ๋ ๋ฐฉ์์ ์ฅ์ ์ ์ ์งํ๋ฉฐ ๋ฐ์ดํฐ ํ์ ์ ๋ค๋ฃจ๊ธฐ ์ด๋ ต๋ค.
-
a
-
apply-generic ํ๋ก์์ ๊ฐ ๋ฌดํ๋ฃจํ๊ฐ ๋๋ค
(apply-generic 'exp_ <complex> <complex>) (apply-generic 'exp_ (complex->complex <complex>) <complex>) (apply-generic 'exp_ (complex->complex (complex->complex <complex>)) <complex>) ... (apply-generic 'exp_ (complex->complex ... (complex->complex <complex>)) <complex>)
-
-
c
-
ํ์ ์ด ๊ฐ์ ๊ฒฝ์ฐ ์๋ฌ๋ก ์ฒ๋ฆฌํ๋ค
(define (apply-generic-c op . args) (let ((type-tags (map type-tag args))) (let ((proc (get op type-tags))) (if proc (apply proc (map contents args)) (if (= (length args) 2) (let ((type1 (car type-tags)) (type2 (cadr type-tags)) (a1 (car args)) (a2 (cadr args))) (let ((t1->t2 (get-coercion type1 type2)) (t2->t1 (get-coercion type2 type1))) ; ์ด๊ณณ์ด ์ถ๊ฐ (if (equal? type1 type2) (error "No method for these types" (list op type-tags)) (cond (t1->t2 (apply-generic op (t1->t2 a1) a2)) (t2->t1 (apply-generic op a1 (t2->t1 a2))) (else (error "No method for these types" (list op type-tags))))))) (error "No method for these types" (list op type-tags)))))))
-
(define (raisex) (apply-generic 'raise x))
(define (install-scheme-number-package)
...
(put 'raise '(scheme-number)
(lambda (x) (make-rational x 1)))
(define (install-rational-package)
...
(put 'raise '(rational)
(lambda (x) (make-real (/ (numer x) (denom x)))))
(define (install-real-package)
(define (tag x) (attach-tag 'real x))
(put 'add '(real real)
(lambda (x y) (tag (+ x y))))
(put 'sub '(real real)
(lambda (x y) (tag (- x y))))
(put 'mul '(real real)
(lambda (x y) (tag (* x y))))
(put 'div '(real real)
(lambda (x y) (tag (/ x y))))
(put 'make 'real
(lambda (x) (tag x)))
(put 'raise '(real)
(lambda (x) (make-complex-from-real-imag x 0)))
'done)
(define (make-real n)
((get 'make 'real) n))
(install-real-package)