C++とJavaが残したレガシー(ブログ)についてBruce Eckel氏が最近投稿したブログが大きな反響を呼んだ。彼はいくつかの設計ミスについて述べるも、両言語がプログラミング言語の発展において大きな役割を担い、重要な建設的レガシーを残してきたと結論付けた。しかし、これら言語のレガシーについて語るのはまだ早いのではないだろうか。
かつてのC++標準化委員会メンバーであるEckel氏は、この言語とCとの下位互換性に関する意思決定をはじめから回想している。
この言語がいかにして不愉快かつ複雑なもので、しかし同時に適切に設計されたものとなりうるかを理解するには、C++における全てを左右する基本の設計決定、つまりCとの互換性を頭に入れておかなければいけません。Stroustrup氏は、Cプログラマの大半をオブジェクトに移行させる方法は移行をトランスペアレントなものにすることだと方針を固めました(正確には、そのように見受けられました)。つまりCのコードを変更せずにC++にてコンパイルできるようにするということです。
C++は確かにCのディベロッパの大部分をC++に引き付けることに成功したが、互換性の決定は言語の発展に対し深刻なマイナスの影響を与えた。
これ(Cとの互換性)は、極めて大きな制約で、常にC++の最も優れた強みであり、しかも泣き所でもありました。C++を過去に成功させたものに、そして現在複雑なものにしたのは、この互換性です。
例えば、彼は演算子のオーバーロードをC++で使用するのは困難なことを認めている。
彼ら(C++を十分に理解していない人々)は、演算子のオーバーロードは難しすぎてプログラマは適切に使用できないと考えました。これは基本的にはC++に当てはまることです。C++にはスタック・アロケーションとヒープ・アロケーションの両方があり、全ての状況に対処するよう演算子をオーバーロードし、メモリ・リークを引き起こしてはいけないからです。これは確かに難しいことです。
もちろん、このような発言は結局議論を引き起こすこととなる。Archilleas Margaritis氏は、C互換性が争点であるとは考えていない。
私は、Cとの互換性のためにC++がひどい設計であるとは思っていません。AdaはCと互換性がありますが、強力にエンジニアリング設計をリードし、とても優れた言語です。
C++のおかしなところは、Cとのソース・コード・レベルでの互換性です。Cヘッダをインクルードできるようにするため、C++はCのプリプロセッサ・システムを維持しました。これが奇妙な非文脈自由文法へとつながり、Cとの互換性を保たなければいけない非常におかしなシンタックスとなりました。
Michele Costabirle 氏は、当初から標準ライブラリがなかったことがC++の不備の1つであると考えている。
私は、1つのC++の重大な責任は標準ライブラリの欠如であると考えています。
私の記憶が正しければ、Stroustroup氏は「The Design and Evolution of C++(邦題:C++の設計と進化)」の中で、多重継承を支持して標準ライブラリを見送ったと書いていました。私は反対の意味で恩恵を受けることになったでしょうが。
C++についてはさまざまなことが言えるが、1つ確かなことがある。それは、C++によってプログラマはプログラミングにおける地位を1つ高めたということだ。
Eckel氏は同じ調子で別の言語を話題にし、Javaになされたいくつかの設計ミスについてあらためて述べた。
長年、Javaチームの傾向には「演算子オーバーロードは複雑すぎる」という部分がありました。このことと、明らかに誰も下準備をしなかったほか多くの決定事項こそが、Gosling氏やJavaチームが採用した多くの選択を軽視しているという噂が私にある理由です…
プリミティブは「効率のために組み込まれなくてはいけませんでした」。ふさわしい答えは「全てがオブジェクトである」ことに忠実なことと、効率が必要とされる際により下位レベルの作業を行うためにトラップ・ドアを用意することです(これは、結局そうなったように、ホットスポット技術がトランスペアレントに物事をより効率的にすることも考慮したでしょう)。ああそれから、超越関数を計算するのに浮動小数点プロセッサを直接は使えないということもね(これは代わりにソフトウェア中で計算されますが)…
ジェネリクスがいかに不適切に設計されたかについて私が記述した際、「Javaにおいて形成された以前の(ダメな)決定と下位互換性を持たなければいけない」として同じ反応が返ってきました。最近ではますます多くの人がジェネリクスから十分な経験を得、本当に使いにくいものであることを理解しています。
Bill Venners氏の記憶は異なっている。
演算子オーバーロードを除外する選択をしたのは下準備がなかったせいだという印象をどこで持ったのかについては、よくわかりません。私がGosling氏と行ったインタビューの1つで、なぜ演算子オーバーロードを除外したのかを彼に質問したことを覚えています(その質問と回答は結局公開されなかったと思います)。彼が私に話したことはおおむね、彼が他の場面で話すのを聞いたことがありました。Gosling氏は、彼が他の言語で(これがC++だけのことなのかはわかりませんが、確実にC++を含んでいます)実際に遭遇した演算子オーバーロードの誤用の程度は、そのメリットを打ち消すものであったと感じたそうです。それだけです。主観的な設計選択だったのです。
James Watson氏はJavaに意図的に導入された制約を支持している。
Javaのコードについていくのが簡単だということで、Javaがこれらの場によくフィットするものになりました。ええ、どのような言語でもメンテナンス不可能なコードを書くことができますが、Javaでそれに取り組まなければいけません。Javaは、多言語で誤用するのが簡単な仕様はあまり備えていません。
個人的な視点では、これはひどいことです。私がある仕様を使いたくないなら、それを使わないでしょう。すべきこと、すべきではないことを教えてくれるSunとは何者でしょうか。しかし、優れたアプローチとは何かについて異なるアイディアを持つディベロッパのグループを採用する場合、そのあり方は変わります。物事を行う方法の数を制限することが、意味を帯びだすのです。
Noel Grandin氏は一言付け加え、新しい言語も含め議論をさらに広げた。
RubyやScalaのようなほかの「ホットな」言語の大部分は、決して主流とはならないでしょう。というのは、これらはコードの読み込みのかわりにコードの記述にひどく偏っているからです。
Javaはこのバランスが適切でした。Javaは冗長で、「クールな」仕様に欠けているかもしれませんが、あるランダム・コードが行っていることを非常に簡単に理解できるのです。
最後に、Eckel氏はJavaのレガシーについて語った。
Javaは、プログラマの主流をガベージ・コレクション、仮想マシン、そして一貫性のあるエラー・ハンドリング・モデル(特にチェックされる例外をサブトラクトする場合、私が「Thinking in Java(邦題:Bruce EckelのJavaプログラミングマスターコース)」の第4版で紹介している使用可能な技術です)へと引き込みました。その全ての弱点を持ってして、私達はより高度な言語の備えがある現在の地点へとレベルアップしたのです。
最もプラスなファクターは、将来の言語への道筋を整えていることである。
ある時点では、C++は最も重要な言語であり、人々はこれからも常にそうであろうと考えていました。多くの人がJavaについて同様に考えていますが、JavaはJVMのためにJava自身を他で取って代わりやすいものとしました。今では、誰かが新言語を作り、Javaと同じくらい効率的に実行できます。…
そして私達はこのことが起こるのを目の当たりにしています。Scalaといったより高度な静的言語、そしてGroovy、JRubyやJythonのように新しくて移植可能な動的言語などです。…
意図的ではないメリット、つまりJavaの予想外に優れていた点は、Java自身はこれ以上発展できないところに到達してしまったけれども、Javaの後継のために極めてスムーズな道を切り開いたことです。全ての将来の言語はこのことから学ぶべきでしょう。つまり(PythonやRubyが行ってきたように)リファクタリングされることが可能な文化を作り出すか、競合種が成功するのを受け入れるか、ということです。
Javaはその登場時に、特にC++ディベロッパと新しく登場したJavaディベロッパとの間で多くの議論を引き起こした。その後発言は落ち着き、今では私たちの現状と両言語が残したレガシーをよりはっきりと認識できている。あるいはもしかすると、レガシーについて話すのは早すぎるのだろうか。これらの言語が忘れ去られた、あるいは衰退しつつあるもののような印象を与えるかもしれない。(ご意見をどうぞご遠慮なくお寄せください)
原文はこちらです:http://www.infoq.com/news/2009/03/C-Plus-Plus-Java-Legacy