いわゆる Haxe の enum というやつ。 これがないとプログラミングできない。
たとえば、
data Tree a = Node (Tree a) (Tree a) | Leaf aと書いた場合、これはオブジェクト指向的には
sealed trait Tree[T]
case class Node[T](left: Tree[T], right: Tree[T]) extends Tree[T]
case class Leaf[T](value: T) extends Tree[T]こういうものを書いたことになる。 この例は Scala なのでまだ良いけど Ruby の場合
class Tree; end
class Node < Tree
def initialize(left, right)
@left = left
@right = right
end
end
class Leaf < Tree
def initialize(value)
@value = value
end
endこんなに書かないといけない、マジで死ぬ
ちなみに CoffeeScript とかだと
class Tree
class Node extends Tree
constructor: (@left, @right) ->
class Leaf extends Tree
constructor: (@value) ->みたいにコンストラクタの引数に @ をつけると
その名前で初期化してくれるのでまぁ幸せ、でもやっぱり
いちいち extends とかしないといけないのめんどう
C++ ではコロンで区切るとアレしてくれるみたいだけど同じ名前を4回くらい書かないといけない (フィールドの宣言,仮引数の宣言,初期化するフィールドの名前の 指定,初期化する式の指定)くて 死ぬ
@人類 コンストラクタを人間に書かせるな
mutable なものは人間には扱えない、助けてくれ
データが基本的に immutable であるので、データがどう操作されるのかわかりやすい、 バグりにくい。
Ruby や Python といった言語でもデータを破壊するような
関数やメソッドの使用は、効率的に処理するとき以外はあまりよくない。
(Python でも lst.sort() より sorted(lst) 、 lst.reverse() より reversed(lst) のほうがいいよね?)
このことは On Lisp などにも書かれている。
全体として、オブジェクト指向言語と関数型言語だと、関数型言語の方が 高度な型システムを持っていることが多い。
Lisp のような例外もある。 ちなみにどういうわけか Typed racket や core.typed とか shen みたいに Lisp ではオプショナルで型システムが提供されることが多いみたいだけど使ってる人見たことない。 (静的型システムは不要と考える文化もある)
TypeScript はすべて nullable 型だ、助けてくれ
どんな型にでも null は代入できるなんて狂った仕様だ。 みんなそんなにヌルチェックが好きなのだろうか?
C++ では生ポインタじゃなくて参照を使う意義はヌルを許容しないからって理由が大きいのだそうだ[要出典] とにかくヌルを型レベルで区別できるようにするのは大事だ。
人間がミスしてもコンパイラが怒ってくれることが動的言語やセグフォ/ヌルポしまくるオブジェクト指向言語に 比べて少ない。
変数名を間違えるなんてよくあるミスだし、変数の解決が静的におこなわれない動的言語では それがいつまでも発見されないこともしばしばある (エディタの補完? それじゃ不十分だ、入力が曖昧だったとき 誤った名前が補完されてそれに気づかないこともある)
眠いときは完全に間違った +goto fail; goto fail;+ なんてコードもよく書く
もちろん完全にミスをなくせるわけではないけど、ミスしにくいというのは重要な要素だ。
関数型erがいつも再帰とか使って関数型チックなコードを書いてるわけじゃないし、むしろ、 Maybe/Either による例外のような広域脱出、 Control.Monad.Trans.Loop による break/continue とかを使ったコード、 ref (ocaml) や IORef で書き換え可能なローカル変数を使ったり、 Control.Monad.Reader Control.Monad.State とかでちょっとしたグローバル変数 (Reader のほうは const グローバル定数で、 State は mutable グローバル変数をつくれる)を使って、 手続き的にコードを書くこともよくある。というかたぶんそっちのほうが多い。
じゃあなんで 関数型使うのか? っつーと基本的な動機は上に上げた、代数的データ型/immutable な構造/現代的な型システム /Maybe / ミスしにくいみたいなことを動機に使ってる。そういう要素を持つオブジェクト指向言語があればもちろん 関数型じゃなくてオブジェクト指向でもいい(それはScalaのことですね?)、けど基本的にそういう要素を持つ 言語は関数型であることが多いっつー話だ。
関数型言語を好きな人はみんなプログラミング言語が好きだ。