SICP 第2章「Building Abstractions with Data」【後編】

後半はGeneric Procedure関する解説。

オブジェクト指向の言語で開発を行っていると、「そもそも型とは」というようなことを考える機会がほとんどない。言語のプリミティブな機能を利用して、型の仕組みを実装してみるのはなかなか貴重な経験だ。

ここでは、Generic Procedureを実現するための戦略が3つ紹介される。

message-passingは非常にオブジェクト指向的だ。直交座標系で複素数を表現する、以下の例が紹介されている。

:::lisp
(define (make-from-real-imag x y)
  (define (dispatch op)
    (cond ((eq? op 'real-part) x)
          ((eq? op 'imag-part) y)
          ((eq? op 'magnitude)
           (sqrt (+ (square x) (square y))))
          ((eq? op 'angle) (atan y x))
          (else
           (error "Unknown op -- MAKE-FROM-REAL-IMAG" op))))
  dispatch)

つまり、処理の塊としての函数が返却される。 利用する側は、以下の様なコードを書けば良い。

:::lisp
(define real-imag (make-from-real-imag 2 2))
(real-imag 'magnitude)

;; 実行結果
;; gosh < 2.8284271247461903

かなり、オブジェクトっぽい。3章ではクロージャがでてくるので、いよいよデータと手続きが一緒になったデータを定義できるようになるだろう。

この後、継承などについても軽く触れていたが、この本ではクラスや継承などについて深くは扱わないようだ。もう少し理解が深まったら型システムなどもじっくり勉強してみたい。