関数とメソッドが違わなければならないたった一つの理由

関数は、引数に対して一意性があり、同じ引数を与えると必ず同じ値が出力される。 メソッドは外部の値の影響を受けるため、同じ値になるとは限らない。

いじょうおわり。 とはいうものの…数学的な概念としての関数とメソッドが違うのは分かるよ。 でもプログラマが実用する上で区別する必要あるの? Javaなんか関数はなくてメソッドしかないんでしょ。 言語の中に複数の概念を持つ必要はどこにあるの? 副作用を持つメソッドと持たないメソッドとして捉えてされいればいいんじゃないの? というのが長年疑問だった。

Scalaを触ってみて、関数型の概念を含んだ言語では関数という言葉に対してもう一ひねりあるようなので、 長年ほっぽっていたもやもやの解消を兼ねて勉強しなおしてみた。

今まで持っていたのはこういうイメージ。

メソッドはインスタンスの状態に依存するようになったことで、数学的に関数とはいえなくなった

(http://d.hatena.ne.jp/amapetas/20111114/1321237707) ということ。まさに同感。

でもだからって区別するひつよ(ry しかも、Scalaみたいな関数型の概念を含んだ言語だと、 ファーストクラスオブジェクトという新たな概念が入っている。 これってつまり、どういうことなの? Lispのような純粋な関数型であれば関数というのも分かるが、 Scalaのようなオブジェクト志向型の中に関数という概念が必要な理由が分からない。 せっかくオブジェクトの中に用意するのであれば、 オブジェクトの状態の参照、変更のための手続きにするものじゃないの?

いろいろ調べていたら、 Functional Scala: Functions ≪ brain driven development と、それをdigitalsoulさんが翻訳をされているものを見つけた。

こういうことなのかな?

・ファーストクラスオブジェクトとして受け渡しする以上、関数型というものがある ・関数型のオブジェクトを評価すると関数の実行結果が得られる 例)addFunctionの場合、関数自体の型は( Int, Int ) => Intになり、評価結果はIntになる ・メソッドはオブジェクト内のインスタンス等外部状態を参照するので、メソッド自体の受け渡しができない =関数は数式のような法則としての捉え方ができるが、メソッドは外部状態に依存するのでそれ自体を捉えられない →関数型をとる関数は引数や戻り値にできるため高階関数にできるがメソッドはできない

つまり、

オブジェクトの中でdef foobarされているものに関数とメソッドの区別があるわけではなく、 プログラム内で処理を進めるための一要素として定義されている。 数字を表現するInt型と全く並列の概念として、論理を表現する関数型として配置されている。 そのことを指してファーストクラスと呼んでいる。

ということなのか。別物として扱うことのメリットが腑に落ちた。

Written on February 2, 2012