リスト1●Prologの記述例
3段論法に基づく推論を実施できる。
リスト2●Prologで記述した「ハノイの塔」
手順ではなく,条件を記述しただけで処理を実行する。
ハノイの塔
三つの場所があり,そのうち一つに円盤が重なっている。円盤はすべて大きさが異なり,上から下に段々大きくなっている。円盤を最初ある場所から別の場所に移すパズルである。条件は,(1)円盤は1枚ずつ動かす,(2)上に載せる円盤は下のものより小さくなければならない,というもの。ちょっと考えれば分かる単純なパズルだ。(本誌)

現実世界の把握方法を規定する

 先程述べたように,プログラミング言語の目的は人間のプログラミング作業を助けることです。プログラミング言語はコンピュータのためにあるのではなく,人間のためにあるのです。

 では,どうやってプログラミング言語は人間を助けるのでしょうか。

 プログラミング言語はコンピュータに何をすべきか,その手順を教えるためのものです。しかし,プログラミング言語は,ただ手順の表記法を提供するだけではなく,現実世界の把握方法(モデル)も提供しているのです。

 例えばPrologのような論理型言語でプログラムする場合には,世界を述語論理で考えます。述語論理は三段論法のようなルールの積み重ねですから,プログラムとはルールを定義することになります。例えば「ソクラテスは死ぬか」という問題をPrologで記述すると,リスト1[拡大表示]のようになります。これだとちょっと分かりにくいですが,「ソクラテスは人間である」「人間は死ぬ」という2段の条件から,「ソクラテスは死ぬ」という事実を推論しています。これを3段論法と呼びます。

PrologとC++では定義方法が全く違う

 これではPrologがどう動作するのか分かりにくいので,もうちょっとプログラムとしてマシな例も挙げておきましょう。「ハノイの塔」というパズルを解くプログラムです(リスト2[拡大表示])。

 hanoiという処理は二つのルールの組み合わせであると表現したことになります。詳細に見てみましょう。まず

 hanoi(1,From,To,_)
 :- write([From,to,To]),nl.

は,「円盤が一枚しかない時,FromからToへ移動させる」という意味です。そして,ハノイの塔は帰納的な問題ですから,次に「円盤がn枚ある(n>1)場合」を定義します。つまり,(1)n-1枚の円盤をViaに移動させる,(2)n枚目の円盤をToへ移動させる,(3)n-1枚の円盤をViaからToに移動させる,です。

 この定義の仕方は,CやC++,Javaといったプログラミング言語とはかなり違います。つまりプログラムを述語(ルール)として記述するということが,同じ仕事をコンピュータにさせるときの「ものの見方」に影響を与えることになります。Prologはやや極端な例ですが,言語は多かれ少なかれプログラマの「世界の捉え方」を提供しています。手続き型言語は手続き的な世界観を,オブジェクト指向型言語はオブジェクト指向の世界観を,関数型言語は関数的な世界観を提供しているのです。

 コンピュータが直接扱うビットのオン/オフより高度な世界観を提供することで,人間を解決すべき問題に集中できるようにしているのです。こうしてプログラミング言語は人間を助けています。世界観はものの捉え方,考え方に影響を与えますから,人間は想像以上にプログラミング言語から影響を与えられていることになります。

使い勝手がプログラミング言語の差となる

 さて,プログラミング言語は,世界観を提供することで人間を助けていると述べましたが,プログラミング言語の良さは世界観だけで決まるわけではありません。Prologのような極端な例を除けばプログラミング言語が提供する世界観の差はそれほど大きなものではありません。

 実際に差を生むのはプログラミング言語のユーザビリティです。使い勝手と呼んでもよいかもしれません。長い歴史を持つツールはその発展の歴史の中で洗練され,だいたい似たような使い勝手になるものです。

 しかし,コンピュータもプログラミング言語もまだまだ歴史が浅い存在で,どのようなものが使い勝手が良いのかははっきり分かっていません。ですから,言語による使い勝手の差はかなり大きなものになっています。

 Webユーザビリティの専門家であるJakob Nielsen博士によれば,ユーザビリティには以下の五つの構成要素があるのだそうです。(1)学習容易性,(2)効率性,(3)記憶性,(4)エラー,(5)満足度,です。これらは当然プログラミング言語にもあてはまります。

すぐに習得できるかが第1のポイント

 「学習容易性」とは,初めてそのデザインに触れたユーザーが,どれくらい容易に基本的なタスクを達成できるようになるかです。プログラマはたいてい既存の言語を一つや二つ知っているものですから,プログラミング言語の「学習容易性」には既存の言語とあまりかけ離れていないことが重要です。Prologのような基本的な考え方から異なっている言語は学習容易性は低くなると考えられます。もっとも,既存の言語とまったく違わなければ,その言語の存在価値もありませんから難しいところです。重要なところに絞って独創性を発揮するとか,学習容易性よりも効率性を選ぶなどのトレードオフを考える必要があります。

一度習得したら効率の良さが大事

 「効率性」とは,いったんそのデザインを学習したユーザーが,どれくらい迅速にタスクを達成できるようになるかを意味しています。プログラミング言語の場合,これは「いかに簡潔にプログラムを記述できるか」と言い換えることもできます。プログラミング言語の目的は「人間を助けること」,別の言い方をすれば人間がより効率よくプログラミングできるよう支援することですが,そのためには簡潔にプログラムが記述できることが重要です。『ソフトウェア開発の神話』という古典的な名著がありますが,その中で著者のFred P. Brooks氏は「基本的な1ステートメントを製造するに要する工数は,(言語によらず)ほぼ一定であろう」「適当な高級言語を用いることによってプログラミングの作成効率は5倍くらい増大させることができる」と述べています。より簡潔に表現できれば,より効率よくプログラミングできるというわけです。

 『ソフトウェア開発の神話』は30年近く前の書籍ですから,この比較で念頭にあった言語はアセンブラとPL/Iでした。しかし,最近のより開発効率のよい言語と,よく整備されたライブラリを利用すれば生産性の差は5倍どころか100倍,場合によっては1000倍にもなるでしょう。

 「記憶性」とは,しばらく使用しない期間をはさんだ後,再びそのデザインに戻ってきたユーザーが,どれくらい容易に習熟度を取り戻せるかです。プログラミング言語の場合では,「学習容易性」と同様に,既存の言語やプログラマが慣れ親しんだ考え方からあまり離れていないことが重要です。また,文法をはじめとするルールの単純さや一貫性が役に立つと思われます。

エラーしにくい方がよい

 「エラー」とは,ユーザが犯すエラーの数,そのエラーの深刻さ,そして,そのエラーからの回復の容易さはどうか,ということです。プログラミング言語の場合,エラーを引き起こしやすいデザインの欠陥がないこと,プログラミング上のエラー(バグ)が致命的な問題を起こさないこと,できるだけ多くのバグが自動的に検出できることなどがあります。

 プログラミング言語における「エラーを引き起こしやすいデザインの欠陥」としては,「記号の多用」「無限の柔軟性」「予想に反する挙動」などがあります。記号の多用が欠陥となるのは,記号は具体的な名前より意味を覚えるのが難しいからです。「記憶性」にも悪影響があります。たとえばPerlの特殊変数「$/」や「$;」の意味を即座に言える人は普通ではないと思います。Rubyにも特殊変数はありますが。

 柔軟性がありすぎるのも問題です。C言語における型の宣言は任意に組み合わせることができますが,複雑になると普通の人間には手に負えなくなってしまいます。極端な例ですが

 volatile int (*foo)(int(*[ ])(),
 char*[ ])

が何を意味するのか理解するのは困難です。

 予想に反する挙動をされるのもエラーの原因です。Pascalの文法ではセミコロン(;)は文と文の間を区切る記号ですが,Pascalプログラムを読んでいるとほとんどすべての文の末尾にセミコロンがついているため,つい文の終わりの印のように感じてしまいます。たいていはそう思っていて問題はないのですが,あるケースでは文法エラーになってしまいます。Cでは最初からセミコロンが文の終わりの印ですから,そのような問題は起こりません。

 ここでは文法についてのみあげましたが,ライブラリの設計など他にもたくさんあると思います。

楽しく使えると満足できる

 「満足度」とは,そのデザインを使うのは,どれくらい楽しいか,です。プログラミング言語の楽しさを言葉で表現するのは大変難しいことですが,事実,使っていて楽しい言語とそうでない言語は存在します。重要なのは気持ちよくプログラミングできるかどうかではないでしょうか。

 気持ちよくプログラミングできるということは,プログラミングという思考活動を邪魔するものが少ないということです。思考はさまざまな要素によって妨げられます。頻繁な待ち時間,思わず発生するバグ,覚えきれない仕様,引きにくいリファレンス・マニュアルなどなど。そのような些細なことの積み重ねで満足できたりできなかったりするのではないでしょうか。

 しかし,はっきり言って今までの言語の多くはユーザビリティのことなど考えられていませんでした。特にツールの拡張用簡易言語というルーツを持つスクリプト言語にはそのようなものが目立ちます。実際,言語というものは問題解決という目的達成のためのツールであり,しかも問題解決という大きな目標からみれば使い勝手はそれほど大きな要素ではありません。ですから,使い勝手の向上のための努力が払われてこなかったことは当然だったかもしれません。

 しかし,すでに述べたようにプログラミング言語は,プログラマの生産性と幸福に予想以上に大きな影響を与えます。これからの言語は十分な機能を持つだけでなく,どれだけ使いやすいかが重要になってくるのではないでしょうか。