オブジェクト指向言語Haskell始めました
最近Haskellをいじってました。その中で思ったんですが、これはオブジェクト指向言語でしょ?Common Lispの教科書[1]に出てくるCLOSの例が意味的にそのままで動きますもの。
ちょっといじってはありますが、Common Lispでは、
(defclass triangle ()
((base :accessor triangle-base :initarg :base)
(altitude :accessor triangle-altitude :initarg :altitude)))
(defclass rectangle ()
((width :accessor rectangle-width :initarg :width)
(height :accessor rectangle-height :initarg :height)))
(defclass circle ()
((radius :accessor circle-radius :initarg :radius)))
(defmethod area ((figure triangle))
(* 1/2
(triangle-base figure)
(triangle-altitude figure)))
(defmethod area ((figure rectangle))
(* (rectangle-width figure)
(rectangle-height figure)))
(defmethod area ((figure circle))
(* pi (expt (circle-radius figure) 2)))
(setf figures
(list (make-instance 'triangle :base 2 :altitude 4)
(make-instance 'rectangle :width 2 :height 4)
(make-instance 'circle :radius 2)))
(print (mapcar #'area figures))
のように書きます。
実行すると、
$ clisp shape.cl
(4 8 12.566370614359172954L0)
これをHaskellで書くと、
data Figure = Triangle Double Double
| Rectangle Double Double
| Circle Double
area :: Figure -> Double
area (Triangle base altitude) = base * altitude / 2
area (Rectangle width height) = width * height
area (Circle radius) = radius ^ 2 * pi
figures = [Triangle 2 4, Rectangle 2 4, Circle 2]
main = do
print $ map area figures
でほぼ同じ。
実行すると、
$ runghc figure.hs
[4.0,8.0,12.566370614359172]
で結果もほぼ同じ。当たり前ですけど。
オブジェクト指向言語の定義は無いですが、大まかに分けて、
- Smalltalk型
- C++型
- CLOS型
の3種類です。HaskellはCLOSとほぼ同じに書けるわけですから、CLOS型のオブジェクト指向言語です。
まあ、定義の無い中での話ですから異論はあるでしょうけど。そもそもCLOSはオブジェクト指向じゃないとかもありですし。
Haskellもオブジェクト指向言語だと考えると、オブジェクト指向言語と関数型プログラミング言語は排他的なものではないことがよくわかりますよね。
大まかに
という感じで理解しています。命令型は指定された順番に実行するもの。宣言型はルールを記述して世界を作り、そこにデータを入れて結果を得るものでしょうか?
よく命令型プログラミング言語の下にオブジェクト指向言語を入れてしまいますが、オブジェクト指向言語は構造化プログラミングの基本路線を維持したまま、その先を目指した言語の総称のようなもので、そこで使われる機能は多岐に亘るので、安易にまとめて名前を付けるようなものではない気がします。
なるべくオブジェクト指向とか言わないようにしましょう。言うなら、カプセル化や継承とかのもう少し具体的な機能にしましょう。
そういえば、Haskellの型クラスは継承機能がありますよね。それでもHaskellはオブジェクト指向言語とは呼ばれないわけですから。
ということで、このブログのタイトルは間違っています。
コメント
コメントを投稿