sicp ch2 5 - andstudy/forge GitHub Wiki

2.5 ์ผ๋ฐ˜ํ™”๋œ ์—ฐ์‚ฐ ์‹œ์Šคํ…œ

์ง€๊ธˆ๊นŒ์ง€ ๊ณต๋ถ€ ํ•œ ๊ฒƒ

  • 2.1 ๋ฐ์ดํ„ฐ์š”์•ฝ
    • ํ”„๋กœ์‹œ์ €๋ฅผ ์–ด๋–ป๊ฒŒ ์งฐ๋Š”์ง€ ๋ชจ๋ฅด๋”๋ผ๋„ ๊ฐ™์€ ์ผ์„ ํ•˜๊ธฐ๋งŒ ํ•œ๋‹ค๋ฉด, ์„œ๋กœ ๋‹ฌ๋ฆฌ ๋งŒ๋“  ํ”„๋กœ์‹œ์ €๋ฅผ ๋งž๋ฐ”๊ฟ” ์“ธ ์ˆ˜ ์žˆ๋‹ค.
  • 2.4 ์š”์•ฝ๋œ ๋ฐ์ดํ„ฐ์˜ ํ‘œํ˜„์ด ์—ฌ๋Ÿฌ ๊ฐ€์ง€์ผ ๋•Œ
    • ์—ฌ๋Ÿฌ ํ‘œํ˜„ ๋ฐฉ์‹๊ณผ ๊ทธ์— ๋”ฐ๋ฅธ ๋ฐ์ดํ„ฐ ์—ฐ์‚ฐ ์ฝ”๋“œ๋ฅผ ์„œ๋กœ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ผ๋ฐ˜ํ™”๋œ ์—ฐ์‚ฐ์„ ์ •์˜ํ•ด ์‚ฌ์šฉ
      • ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ
      • ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ

๋ชฉํ‘œ

  • ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ ๊ธฐ๋ฒ•์„ ๋ฐ”ํƒ•์œผ๋กœ ์ง€๊ธˆ๊นŒ์ง€ ๋งŒ๋“  ์‚ฐ์ˆ  ์—ฐ์‚ฐ ๊พธ๋Ÿฌ๋ฏธ๋ฅผ ๋ชจ๋‘ ํ•ฉ์ณ์„œ, ํ•œ ๋ฉ์–ด๋ฆฌ ์‚ฐ์ˆ  ์—ฐ์‚ฐ ๊พธ๋Ÿฌ๋ฏธ๋กœ ์งœ ๋งž์ถ”์ž

2.5.1 ์ผ๋ฐ˜ํ™”๋œ ์‚ฐ์ˆ  ์—ฐ์‚ฐ

  • ์ผ๋ฐ˜ํ™”๋œ ํ”„๋กœ์‹œ์ €๊ฐ€ ์ธ์ž์˜ ํƒ€์ž…์— ๋”ฐ๋ผ ์•Œ๋งž์€ ๊พธ๋Ÿฌ๋ฏธ๋กœ ์ผ์„ ๋„˜๊ธฐ๊ฒŒ ๋งŒ๋“ ๋‹ค

    • ์˜ˆ) ์ผ๋ฐ˜์ˆ˜, ์œ ๋ฆฌ์ˆ˜, ๋ณต์†Œ์ˆ˜๋ฅผ ๋”ํ•˜๋Š” 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์˜ ์ธํ„ฐํŽ˜์ด์Šค์™€ ๊ฐ‡ํžŒ ํ”„๋กœ์‹œ์ €๋ฅผ ์ •์˜ํ•˜๋ฉด ๋œ๋‹ค.

์—ฐ์Šต๋ฌธ์ œ

2.77

  • 3+4i๋ฅผ ์ง๊ต์ขŒํ‘œ๋กœ ํ‘œํ˜„ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•๋Œ€๋กœ ์ €์žฅ๋˜์–ด์žˆ๋‹ค

    • ('complex . ('rectangular . (3 . 4)))
  • real-part ํ˜ธ์ถœ์‹œ ํ”„๋กœ์‹œ์ €๊ฐ€ ์ ์šฉ๋˜๋Š” ์ˆœ์„œ

    • ์ผ๋ฐ˜ํ™”๋œ real-part
      • apply-generic
    • complex ๊พธ๋Ÿฌ๋ฏธ์˜ real-part
      • apply-generic
    • rectangular ๊พธ๋Ÿฌ๋ฏธ์˜ real-part
  • ๋ฐ์ดํ„ฐ์˜ ๋ณ€ํ™”

    • ์ผ๋ฐ˜ํ™”๋œ real-part ์ธ์ž
      • ('complex . ('rectangular . (3 . 4)))
    • complex ๊พธ๋Ÿฌ๋ฏธ์˜ real-part ์ธ์ž
      • ('rectangular . (3 . 4))
    • rectangular ๊พธ๋Ÿฌ๋ฏธ์˜ real-part ์ธ์ž
      • (3 . 4)
    • ๊ฒฐ๊ณผ
      • 3

2.78

  • 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)
    

2.7

    ; ์ผ๋ฐ˜ํ™”๋œ ์—ฐ์‚ฐ
    (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)))))

2.80

    ; ์ผ๋ฐ˜ํ™”๋œ ์—ฐ์‚ฐ
    (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)

2.5.2 ํƒ€์ž…์ด ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฎ์–ด ์“ฐ๋Š” ๋ฐฉ๋ฒ•

  • ์ง€๊ธˆ๊นŒ์ง€ ์ •์˜ํ•œ ์—ฐ์‚ฐ์€ ๊ผด์ด ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋กœ ์™„์ „ํžˆ ๋…๋ฆฝ๋œ ๋ฐ์ดํ„ฐ๋กœ ๋ฐ›์•„๋“ค์ด๊ณ  ์žˆ๋‹ค.
    • ์ง€๊ธˆ๊นŒ์ง€๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์˜ ๊ฒฝ๊ณ„๋ฅผ ๊ฐ€๋กœ์ง€๋ฅด๋Š” ์—ฐ์‚ฐ์ด ์—†๋‹ค.

์„ž๋ถ™์ด๊ธฐ ์—ฐ์‚ฐ

  • ์„œ๋กœ ๋‹ค๋ฅธ ํƒ€์ž… ์‚ฌ์ด์—์„œ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๋Š” ์—ฐ์‚ฐ๋งˆ๋‹ค ๊ทธ์— ํ•ด๋‹นํ•˜๋Š” ํ”„๋กœ์‹œ์ €๋ฅผ ํ•˜๋‚˜์”ฉ ์„ค๊ณ„

      (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๊ฐœ์˜ ํ”„๋กœ์ง€์„œ๊ฐ€ ํ•„์š”
  • ์œ„์™€ ๊ฐ™์ด ๊ตฌํ˜„ ํ–ˆ์„๋•Œ์˜ ํ•œ๊ณ„

    • ๋‘ ๋ฌผ์ฒด ์‚ฌ์ด์—์„œ ์„œ๋กœ ์–ด๋А ์ชฝ ํƒ€์ž…์œผ๋กœ๋„ ๋ฐ”๊ฟ€ ๋ฐฉ๋ฒ•์ด ์—†์ง€๋งŒ ๋‘ ๋ฌผ์ฒด๋ฅผ ์•„์˜ˆ ๋‹ค๋ฅธ ํƒ€์ž…์œผ๋กœ ๋ฐ”๊พธ๋ฉด ๋ฐ”๋ผ๋˜ ์—ฐ์‚ฐ์ด ๊ฐ€๋Šฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

ํƒ€์ž…์˜ ๊ณ„์ธต ๊ด€๊ณ„

  • ํƒ‘
    • ๋ฐ์ดํ„ฐ ํƒ€์ž…๋งˆ๋‹ค ๊ทธ ์œ„ ํƒ€์ž…์ด๋‚˜ ์•„๋ž˜ ํƒ€์ž…์ด ๋งŽ์•„์•ผ ํ•˜๋‚˜์ธ ๊ณ„์ธต ๊ด€๊ณ„
  • ์žฅ์ 
    • ์œ„ ํƒ€์ž…๊ณผ ์•„๋ž˜ ํƒ€์ž…๋งŒ ๋ฐํžˆ๋ฉด ๋œ๋‹ค.
    • ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์ง‘์–ด ๋„ฃ๊ธฐ ์‰ฝ๋‹ค.
    • ๋ฌผ๋ ค ๋ฐ›๋Š” ๊ฐœ๋…์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ ๊ฐ€๋Šฅ
    • ๋Œ์–ด ๋‚ด๋ฆฌ๊ธฐ ์‰ฝ๋‹ค.

๊ณ„์ธต ๊ตฌ์กฐ๊ฐ€ ์ง€๋‹Œ ๋ฌธ์ œ์ 

  • ํ•œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์— ์•„๋ž˜ ํƒ€์ž…์ด ์—ฌ๋Ÿฟ ์žˆ์„ ๊ฒฝ์šฐ
  • ํ•œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์— ์œ„ ํƒ€์ž…์ด ์—ฌ๋Ÿฟ ์žˆ์„ ๊ฒฝ์šฐ
  • ๋ชจ๋“ˆ ๋ฐฉ์‹์˜ ์žฅ์ ์„ ์œ ์ง€ํ•˜๋ฉฐ ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ๋‹ค๋ฃจ๊ธฐ ์–ด๋ ต๋‹ค.

์—ฐ์Šต๋ฌธ์ œ

2.81

  • 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)))))))
      

2.83

    (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)
โš ๏ธ **GitHub.com Fallback** โš ๏ธ