関数型言語の学習コスト

http://d.hatena.ne.jp/chuusotsu_neetan/20090411/1239445900

猿なみの知能しか持ち合わせていない奴の相手はしないんだが、15歳の少年という事なんで特別に教えてやろう。

関数型言語の学習コストが高いのは、別に言語仕様が難しいからじゃない。お前がやってるような、サンプルを作って動かすだけなら誰にでもできる。

難しいのは、プログラムを作る対象の処理が手続きだからなんだよ。

関数型言語で数学の計算をするなら何の問題もない。だけどな、数学の問題を解くようなプログラムを作るプログラマなんて一握りもいないんだよ。大抵のプログラマは実際に行われている業務をコンピュータでやらせる為のプログラムを作ってるんだよ。

この実際の業務ってのは、ほぼ全てが手続き。例えば「お使い」の指示書を作るとするとこうなる。

依頼主から、商品の名前と、お金を貰う。
店に行って、商品の名前と同じ商品を取る。
レジに商品とお金を渡して商品とお釣りを貰う。
依頼主にお釣りと商品を渡す。

大ざっぱだが、これは手続き型だ。これが普通なんだよ。これを関数にしたらこうなる。

お使は、依頼主に依頼主から貰った商品の名前とお金で買い物をして渡す。
買い物は、商品の名前と同じ商品を取ってお金と精算する。
精算は、お金と商品をレジに渡して、商品とお釣りをもらう。

これじゃ、指示を受けた人がわからねえよ。これ処理してみよろ

依頼主は、お母さん。
商品は、大根。
お金は100円。

依頼主から、商品の名前と、お金をもらう。
店に行って、商品の名前と同じ商品を取る。
レジに商品とお金を渡して商品とお釣りをもらう。
依頼主にお釣りと商品を渡す。

お使いをお母さんでする。

お使は、依頼主に依頼主から貰った商品の名前とお金で買い物をして渡す。
買い物は、商品の名前と同じ商品を取ってお金と精算する。
精算は、お金と商品をレジに渡して、商品とお釣りをもらう。

意味わかるか?


世の中は関数で動いてるわけじゃない。お前が勉強してるHaskellのドキュメントが関数で記述されてたら、読めねえぞ。仕事も、文章も何もかもが手続き。人間は手続きで考えるんだよ。

関数型言語を使おうとすると、その手続きを関数に置き換えないといけなくて、その能力を身につけるコストってのが関数型言語の学習コストなんだよ。

お前が勉強してるHaskellなんて使うだけなら1週間もあれば使えるようになる。プログラマが難しいって言ってるのは、今の仕事でHaskellを使った場合どうなるのかを考えるからなんだよ。

DSLの間違ったアプローチ

Scalaのような、既存vmに相乗りした言語や言語内言語の間違ったアプローチ

既存vmに相乗りした言語

既存vmに相乗りする場合、そのvmがOSの用に汎用マシンとして設計されていれば問題ありませんが、jvmJava用のvmであるように何かの言語用のvmとして設計されている場合、直接jvmバイトコードを生成したり、クラスを生成する方法は間違っています。

jvmバイトコードを生成している場合は、ローカル変数フレームを内部処理用に予約しておく等の特殊な事ができるため、言語仕様によってはJavaを超えることができる可能性があります。しかしJavaコンパイラの行っている最適化の恩恵は受けることが出来ません。

しかし、所詮プリプロセッサです。これはCコンパイラC++プリプロセッサとは意味が異なります。jvmは仕様を見てもJava用のvmであることは明らかです。ACC_PUBLIC、ACC_PRIVATE、ACC_PROTECTED等とは別のアクセスフラグを作る為にはそのためのJavaのコードが必要になります。

jvmネイティブの処理はJava用の処理です。jvm用のバイトコードを作ることは、バイナリを作るのとは意味が異なりJavaの仕様の制約の中で処理を行う必要があるため、結局はJavaで書く方がパフォーマンスが高くなります。

他の言語用のvmを使用している限りパフォーマンスが必要になるような汎用言語を目指す事は間違いです。

シンタックスの違いしか無い言語

主流になっている言語に無駄なシンタックスは無いと思った方が良いです。そのシンタックスを変更するという事は、何かの機能が失われたり、他のシンタックスに影響が出ます。

ありがちなのが、変数の型宣言を省略できるという機能ですが、そのために変数の宣言用のvar等のたのシンタックスが必ず必要になります。全てはトレードオフです。

元言語より全てにおいて優れているシンタックスは作れないのです。そのためDSLはWEB、ゲーム、シュミレーション等の用途に限定し機能的に優れていなければ、存在価値がありません。

しかし、これもライブラリを作ればで十分では意味がありません。そのライブラリを使う上での特殊なシンタックスが必要になって初めて言語とする必要があるのです。

Scalaが主流にならない5つの理由

流行のScalaが主流にならない5つの理由

Javaと同じ汎用言語である

ベース言語であるJavaと適用範囲がかぶっています。Javaを覚える代わりにScalaを覚えるメリットはありません。Javaユーザが乗り換えるとも思えません。つまりJavaを覚えてるいるけどJavaはあまり好きではない人がターゲットになります。どれくらいいるでしょうか。

jvmコードに変換している

jvmのコードに変換してJavaとして動かしている以上、Javaで出来ることしか出来ません。つまり記述の省略、シンタックスシュガー、ライブラリ以上のことはできず、Javaよりパフォーマンスが高くなることもありません。

Javaとの連携が容易

Javaと容易に連携が可能という事を特徴としていますが、Javaと連携を行いJavaのクラスを使うならJavaを覚えてJavaを使えるようになる必要があるため、結局Javaを使うことになるでしょう。

関数型言語の思想が多く取り入れられている

今まで関数型言語が主流になったことはありません。関数型言語は学習コストが高いからです。関数型言語ユーザの中では流行し主流になる可能性は高いですが、関数型言語を使っていない人が使う事はないでしょう。

Javaのライブラリを使うことを前提にしている

グルー言語だということです。グルー言語が主流になることはあり得ません。