関数型とOOP

補足というかなんというか。
そもそもから言えば、関数型言語ではOOPが存在しないとは思っていないのです。SchemeにだってMLにだってオブジェクト指向はあるし、実装自体できる。Cだって、オブジェクト指向っぽく書くことはできる。だけれども、そこに破壊的代入があるべき、もしくはあったほうがよりよいのではないかと思っている、ということです。
例えばSICPにも、銀行口座オブジェクトの例があります(3章)。ここで使われているのも、id:sumiiさんが示してくださったスライドにもあるオブジェクト指向の方針です。つまり、何か状態変化があればnewをして、その新しいオブジェクトをreturnする、ということです。この方針と方法については確かにその通りで、オブジェクト指向自体は実現できると思います。でも、それって本当に効率的なのか?という疑問があるわけです。そして、オブジェクト指向の一部を無視しているのではないか、という疑問もあるわけです。
まず効率の問題として、一つの内部状態を変化させるのに、わざわざ新しいオブジェクトのnewを行うという無駄。まあ、関数型自体がそういうものだと言われれば、その通りなのですが。
そして、オブジェクト指向の一つの目的であるところの、作業の分担というところをちょっと無視しているのではないかと。つまり、内部状態が変化しているかどうかを、そのオブジェクトを使う人がきちんと把握してあげなくてはならない、という点があります。大したことは無いと思うのですが、なんか気持ちが悪い。内部状態を変化させながら値を返すようなメソッドは、存在できないとなるわけです。
で、これって不自由なんじゃないのかなあ、と。それなら最初から素直にset!なりimmutableなりを使って実装してやるのが自然だし、効率的だと思うのです。

二種類の関数

contest


世の中には二つの関数がある。副作用のある関数と副作用の無い関数だ。ということを、http://blog.livedoor.jp/dankogai/archives/50430136.htmlを読んで考えてしまった。
つまり、こういうことだ。副作用がない関数であれば、return等というものは必要がない。値を返すのがメインなのだから、関数が終われば値を返すに決まっている。副作用がない関数で、かつunit(あるいはvoid)を返す関数と言うのは全くの無意味だ。実用上で存在価値はない。
更に言うなら副作用の無いOOPなどOOPでは無いと思う。少なくとも副作用が存在することは仮定して作ってある必要がある。この点が、おそらくHaskellオブジェクト指向になっていない理由なのじゃないかと思ったりしている。
で、CやらJavaScriptやらの言語でreturnが存在している理由としては、基本的に副作用があるからだろう。これが副作用が無ければ確かにreturnは余計に見える。それが、つまりλx.(x + 1)のような関数の場合だ。
しかしながら、もし仮にprint(x);x + 1というような関数だったらどうするか。printという副作用の後、突如出てくるx + 1という式。ここには是非ともreturnと書いておいて欲しい。
先ほどHaskellの例を出したけれども、Haskellのreturnは副作用も存在しうるMonadで使われる構文であると言うことを考えてみると、面白いんじゃないか、とも思った。