先日、「南青山アドベンチャーも挫折した」と書いたが、 その後、記憶をたどるとどうやら私が遊んだ(そして挫折した)のは、その1年前の 表参道アドベンチャーだったようだ。
で、googleすると攻略法が。 コマンドを見てると懐かしい....。
当時Googleがあったら挫折しなくても済んだよなあ。 もっともそれではちっともゲームにならないような気もするが。
それはともかく、攻略法であらためてストーリーを読むととてつもなくつまらない。 こんなくだらない(失礼)ことにのめり込んでいたかと思うと 過去の自分に対して怒りを覚える部分もあったりして。
昨日の続き。
まず言語のユーザビリティを考えるにあたって、ふたつほど明らかにしておかねばならない点がある。
第一には、言語のユーザビリティの定義だ。 ここでは言語のユーザビリティを以下のように定義する。
この二点に優れた言語をユーザビリティが高いとする。 もしこの二つが矛盾した場合には、(私だったら)後者を取る。
次には「万能の言語はない」という点だ。
プログラミング言語はたいてい設計者の予想を越えて適用範囲が広がる傾向があるが、 しかしあらゆる分野に完璧に適合する言語もなければ、あらゆる人にとって使いやすい言語もない。 ある局面では非常に便利な機能が、いつも役に立つとは限らない。
それゆえ、トレードオフについて考慮する必要がある。 たとえば、ある言語がある分野について別の言語より劣るとしても、 その劣る分野がわりと特殊で、 日常的に使う領域では別の言語より圧倒的に使いやすい場合、 しかもその分野によく適合するために普段の使いやすさを損なう可能性があるならば、 今のままにしておいた方がトータルのユーザビリティは高いということになる。
さて、これを前提としてLispを考えてみよう。
なぜLispを題材にするかというと、Lispが優れた言語だからだ。
Lispはながらく生産性の高い言語として、ある種の「秘密兵器」の地位を保持してきた。 Lispの生産性はなにに由来するのか、それは(私の感じる)Lispのわかりにくさとどう関係しているかを 明らかにすることで、可能であればLispよりもユーザビリティが高い言語、 いいかえれば「Lispの生産性を持ちながら(私にとって)わかりやすい言語」が 存在しうるか、もしそうであればそれはどのような言語かということを明らかにしたいと考えている。
Lispの生産性の高さの原因はなんだろう。
くらいだろうか。
最初の4つは最近の動的言語も備えているものが多い特徴だ。 もっとも、真の「統一的なオブジェクトモデル」を実現している言語は意外に少ない。 最近の言語だとSmalltalk(は最近じゃないか)、Ruby、Python(はちょっと苦しい、改善されつつある)くらいか。
「ダイナミズム」は説明が必要だろうか。つまり動的にクラスを定義したり、 プログラムを拡張したりする機能だ。 これがあると実行時にプログラムの振る舞いを変更したり、実行中にデバッグしたりするような 離れ技が使える。
Lispに特徴的な点は後のふたつ、つまり「S式」と「マクロ」である。 S式はつまりプログラムとデータが同じフォーマットであることを意味し、 マクロは文法をユーザが好きにプログラムできることを意味する。
これらは生産性に寄与するか。わかりやすさにはどうか。
私の考えでは、最初の答えはYes、後の答えはNoである。
これも昨日述べたが、S式は冗長である。専用の文法を用いた方がコンパクトな記述になるし、 その文法を学習するためのコストはさほど高くない(よっぽど変な文法でなければ)。
それを取り返すための武器がマクロである。 マクロを使えば自分専用の制御構造も簡単に定義できるし、 関数としては抽象化できないものも抽象化できる余地がある。
つまりLispはS式による冗長さを文法をプログラマブルにすることで克服しようとしているわけだ。 そして生産性(≒記述のコンパクトさ。Paul Grahamによれば)の向上という点ではある程度成功していると言えるかも。
ではわかりやすさについてはどうだろう。
あるプログラムがわかりやすいかどうかは、私の考えによれば、 「あるコードを見た時にその意味を理解するコストが低い」かどうかで決まる。
Lispはこの点では不利だ。
S式の単純さは読み下す時のヒントが少ないことを意味する。 すべてがS式なので、ここはデータ、ここはロジックという情報もプログラムの字面からは得られない。 ヒントが多ければ良いというものでもないが、あまりに少ないのはつらい。
また、生産性の向上に寄与したマクロは、任意に定義されたユーザ言語を定義することと等しいので、 このプログラムが利用しているマクロについての十分な知識がなければ、 コードの構造も理解できないことになる。
結論としては、
であり、タチの良い動的言語であれば、Lispと同等の生産性を、よりわかりやすく実現できる可能性がある、 というものだ。
ま、Rubyの設計者の私の結論としては妥当なものだろう。
さて、これは私の結論であるが、別の意見を持つ方も当然いらっしゃるだろう。 これをきっかけに議論が深まればよいと考えている。
強力で美しいにもかかわらず、Lisp がまつもとさんにとって読みにくい原因は、まつもとさんの中にあるプログラムのモデル(思考パターン)と、それを記述する言語としての Lisp との相性が良くないのだと想像します。逆に私にとって Scheme の方が読みやすいと思うのは、私の持つモデルと Scheme との相性がよいということです。
これはどうなんだろう。 私はかならずしも「(私の)思考パターンとLispの相性が良くない」とは思わない。 私は上で「思考パターン」という概念を用いずに、 「Lispは(私の定義する)ユーザビリティにとって不利」ということを示してみた。
「データ部分とコード部分を区別しなくていいのは利点」というのは、「関数指向のモデルを持つプログラマにとっては」ということです。
これもよくわからない。もしこれが事実だとするならば、なぜHaskellやMLはS式を用いないのだろうか。 逆にLispは関数的にも書けるがその実体は単なる手続き型言語だし。