なぜConcurrent Cleanを使うのか?

[id:w_o:20051011:p1]を読んでいて、何か、思った。
きっと、純粋関数型だとか参照透過だとか高階関数とか、そんなことは関係ないのかもしれない。多相型も、ライブラリ以外では、それほど重要ではないかもしれない。
(書いているうちに、リンク先の日記と関係のない話題になっていってしまった・・・)

まず、型推論は大きい。

静的型付けであるにもかかわらず、変数を宣言する必要がないことは、プログラミングをする上でのある種のストレスを低減するのに役立っている。また、型を書く必要が出たときも、短く、直感的なところはやはり楽だ。

型の書き方の比較
Delphiの例
type TFunction = function (aInt: Integer): Integer;
function AFunction (aInt: Integer): Integer;
Javaの例(*1)
interface TFunction {
  int exec(int aInt);
}
TFunction aFunction = new TFunction() {
  int exec(int aInt) {
    ...
  }
}
Cleanの例
TFunction :== Int -> Int
aFunction :: Int -> Int

型さえ合えば代入できる

事前にインターフェースやスーパークラスなどを定義して置いたり、ポインタを使って危険な綱渡りをしなくても、直感的に代入できそうなところには、大体代入できるのは、余計な気を回さなくてもよい。
ただ、上手く型が合わないと、意図の汲み取りにくいエラーメッセージに頭を悩ませることになるのは、いまいちだが。

関数のスコープが広い

オブジェクト指向でいうところのクラスがないので、不便かと思いきや、なんというか、関数のスコープがすごく広くて、不便を感じないかも。むしろ、インスタンス変数に状態を保存しながら、複数のメソッド間で情報をやり取りしなければいけないクラスベースプログラミングの方が不便に感じたり。
ここで、関数のスコープが広いというのは、関数内関数で親関数のコンテキストを参照したコードを書いたり、カリー化やクロージャで関数内のデータを別の関数に受け渡したりすることができるということを意図している。他にいい言葉が思いつかないので。

実行速度が速い

HaskellでなくCleanを使うの理由はこの点も大きい。Haskellは使ったことがないので、実感はしていないのですが、遅いと評判だから。
あと、Cleanの環境は、インストールも簡単だし、構造も単純でハックしやすいというのも、Haskellではなく、Cleanを選ぶ理由だ。


*1 ああ、このJavaの例は、普通じゃないかも・・・