2012年01月19日

Coders at Work まとめ Part 3

 『Coders at Work』まとめ Part 2の続き。

 

第11章 L Peter Deutsch

・(巨大なソフトウェアについて)

アボガドロ数はご存じでしょう。10の23乗でしたか。だから世界にはものすごい数の小さなものが詰まっていて、同時にたくさんのことが起きています。私たちがそれで患わされることがないのは、たとえばこのテーブルを素粒子レベルで理解する必要がないからです。

 みんなソフトウェアでモジュール化構造を作ろうと試みており、時と共に技術水準は進歩していますが、それでも、私の意見では、周りを見回して10の23乗個の原子をもったものを目にしながら気後れさせられることのないものの世界の簡単さには、遠く及びません。

 ソフトウェアというのは詳細の学問で、それはソフトウェアにまつわる深くぞっとする根本的な問題です。すべての細かい部分同士がどうやり取りするのかいちいち考えずに済むようにできる、ソフトウェアを概念化し組織化する方法が分かるようになるまでは、物事はあまり良くはならないのです。そして私たちはそこから遠く離れたところにいます。

 

・(それは変えることができる?)

 始めからやり直す必要があるでしょう。ポインタの概念を持った言語をすべて捨てることです。現実の世界にはポインタのようなものはないのですから。情報というのは場所を取るものであり、時を経て存在し、特定の位置を占めるという事実を、把握できるようになる必要があります。

 

・私が「記号の世界」と呼んでいる場所は、私にはいつも非常に快適でした。記号とそのパターンというのは、私がいつもランチに食べているものでした。多くの人はそうではありません。私のパートナーでさえそうです。私たちはどちらも音楽家であり、どちらも作曲家であり、どちらも声楽家です。しかし私は音楽の世界に記号という視点でやってきたのです。私は作曲の多くを鉛筆と紙だけでやります。音符はそこにありますが、ピアノから拾い出すわけではありません。彼はそれを聞き、構想を得るのです。

 一方で彼は作曲の多くをギターでやります。彼はギターを弾き、いじり回し、あるいはピアノを少し鳴らし、再び弾き直します。

#「パートナー」が「彼」であることに注目。これ自体は驚くに値しないが、あとで驚愕することになる。

 

・問題は、ビジネスの世界で古くからある言い回しですが、「早い、安い、良い。……どれでも2つ選んでください」というものです。早く構築するなら、安く作る方法はあったとしても、なおかつ良いものにはなりそうにありません。

 

・プログラミング言語については、この40年で質的には進歩していないと強く主張できます。今日使われているプログラミング言語で、Simula-67より質的に優れていると言えるものはありません。奇妙に聞こえるだろうことは分かっていますが、本当にそう思っています。JavaはSimula-67よりさして良くなっているとはいえません。

 

・(Smalltalkも?)

 SmalltalkはSimula-67よりいいとは思いますが、今日のSmalltalkは1976年にはすでにあったのです。今の言語が30年前にあった言語より良くないと言っているわけではありません。私が現在あらゆるプログラミングに使っているPythonは、30年前にあった何よりもずっと良いと思います。Smalltalkよりも好きです。

 私は「質的に」という言葉をとても注意して使っています。今日広く使われているプログラミング言語はすべて、ポインタの概念を持っています。それよりも質的に優れた基本概念に基づくソフトウェア構築方法というものを私は知りません。

 

・(PythonやJavaの参照もポインタ?)

 そうです。PythonやJavaで作られたプログラムであっても、ある小さなスケールを過ぎると、すべて同じ問題にぶつかります。CやC++におけるメモリ破損の問題はなかったとしても。

 問題の本質は、システムの情報共有や情報アクセスのパターンを理解し、記述し、制御し、推測する言語的なメカニズムがないということです。ポインタを渡すとか格納するというのはローカルな操作ですが、その帰結は暗黙にグラフを作るということです。マルチスレッドアプリケションの場合については触れないでおきましょう。シングルスレッドアプリケーションにおいてすら、プログラムの別な部分の間を流れるデータがあります。プログラムの違った部分に伝搬するリファレンスがあります。そして最高に良く設計されたプログラムでも、進行する2つとか3つとか4つの異なる複雑なパターンがあり、細かい部分で起きることを実際に制約するように、大きなユニットの性質を記述し推測し特徴づける方法はないのです。みんなこの問題でやられています。しかしこれに関してブレークスルーがあったとも、広く受け入れられ、広く使われている解決法があるとも見えません。

 

・(関数型言語は?)

 ええ、純粋関数型言語は異なる種類の問題を抱えているにしても、確かにこの難問にある答えを出していますね。

 

・私が言語設計の目論見に実際踏み出さなかった最大の理由はたぶん、共有のパターンやコミュニケーションのパターンを、十分高いレベルで、十分結合可能な仕方で記述する方法を見いだせるだけの洞察を、やってのけられるほど持ち合わせていると自分で思えないからです。しかしこれは今日のソフトウェア構築が30年前からわずかにしか良くなっていない理由だとも思います。

 

・(さまざまな種類のアサーションについて)意図したとおりに動くソフトウェアへの道は、アサーションではなく、帰納的アサーションでもなく、より良く、より強力で、より深い宣言的記法にあると思っています。

 私が好きなコンピュータにまつわる警句の作者のジム・モリスは、型チェッカーはネアンデルタール人の証明器だと言っています。もしブレークスルーが起こるとしたら、それはプログラムがどう構成され何をすると意図されているのかを宣言的に記述する、もっと強力な方法から来ると思います。

 

・もはやLispでプログラムを書かなくなったのは、あのシンタックスに我慢できなくなったからです。シンタックスが重要だというのは紛れもない人生の真実です。

 

・言語システムというのは3本脚の上に立っています。言語があり、ライブラリがあり、ツールがあります。言語の成功は、この3つの複雑な絡み合いに依存しているのです。Pythonには素晴らしい言語があり、素晴らしいライブラリがあり、そしてツールはほとんどありません。

 

・(Lispのシンタックスに我慢できなくなった理由について)平方インチ当たりの情報の密度は、中置記法の言語の方がLispよりも高いのです。

 

・(中置記法の利点について)中置記法の世界では、すべてのオペレータは2つのオペランドと隣り合っています。前置記法の世界ではそうなっていません。もう1つのオペランドを見るために余分な手間がかかるのです。そんなことはみんな小さなことだと思うでしょうけれど、私にとって最重要なのは平方インチ当たりの情報密度なのです。

#思えばオブジェクト指向言語の文法は、関数名の中置記法。

 

・私はコーラスで何年も歌っていましたが、2003年の夏に、私たちはツアーでイタリアの古い教会で6回コンサートをしました。その旅行には妻も同行し、ヨーロッパにさらに2、3週間滞在することにしました。

#「パートナー」は「彼」なのに、一緒に旅行するような「妻」がいる!?!?!?

 

・(ソフトウェア開発の仕事から手を引いたことについて)

 そして突然気づきました。私がワクワクするようなソフトウェアプロジェクトを見つけるのに苦労していたのは、プロジェクトを見つけるのが問題なのではなく、ソフトウェア自体にもはやワクワクしないからなのだと。今から思うとバカみたいに見えますが、私がソフトウェアに打ち込んでいたそもそもの理由は、それによって世界をより良い場所へと変えられると思っていたからなのでした。もうそんなことを信じてはいません。少なくとも前と同じようには。

 

第12章 Ken Thompson

・(もっと違ったようにプログラミングを学びたかった?)

 ええ、もちろん。高校のときにタイピングを習っておけばと思います。今でもタイピングが下手で困っています。でも何もしようと思わなかったし、何もしませんでした。そういうけじめがないんです。私はいつでも次にやりたいことをやって終わりです。私にもっと先見性とか計画性みたいなものがあれば、タイピングのようなことはチャンスのあるときにやっていたと思います。あとは数学をもっと深く学んでいたらとは思いますね。数学が役に立つような場面に確かに出くわしますから。そういった小さなことはたくさんあります。しかし昔に戻ってもう一度やり直さなければならないとしても、何も違ったようにはやらないだろうと思います。基本的に私は何も計画せず、ただ次のステップへと進むだけです。そしてもう一度やらなければならなかったとしても、同じようにただ次のステップを取っていくだけです。

 

・私はコードにはこだわりません。半分進んだところで別なやり方を見つけたなら、ただハックして乗り越えます。私の知っている人の多くは、一行のコードをいったん書いてしまうと、バグでも出ない限りは、それがそのままずっと固まってしまいます。とくにAPIのあるルーチンを書いていて、APIをどこか、封筒裏なりAPIリストなりに書いていようものなら、それで終わりです。どんなにまずかろうと二度と変えられることはありません。私の場合は、もっと良いやり方や分割の仕方を見つけたときには、喜んでまたばらします。既存のコードに執着することはありません。コード自体は常に劣化していくもので、書き換えるにしくことはありません。何も変わらなかったとしても、何かの理由で劣化するのです。

#「コード自体は常に劣化していく」とは仙人か天使でなければ公言できない真実。

 

・(コードを捨てるのはいつ?)扱うのが難しくなったときです。私はほとんどの人より早く見切りをつけます。何かを付け加えたいと思い、それを付け加えるのが難しすぎると感じたらすぐにコードを捨てます。捨ててはじめからやり直し、自分のやりたいことが容易にできる別な区分けを考え出します。私が何かを捨てる引き金はとても軽いのです。

#またもや仙人天使発言。

 

・(Cのポインタはメモリ破壊を引き起こす機能であり、GCする言語のほうが安全、という議論について)

 バグはバグです。バグがある原因は、自分でそれを作ったからです。実行時の安全性という意味で安全な言語なら、悪用し得るバッファオーバーフローを起こすかわりにオペレーティングシステムがクラッシュするだけです。「死のping」はオペレーティングシステムのIPスタックでした。死のpingはもっとあったのではないかと思います。「スーパーユーザになってマシンを乗っ取るping」はなくなったとしても「死のping」は残るでしょう。

#「100パーセント安全でなければダメ」論。彼は天国に住んでいるらしい。Plan 9?

 

・(1999年のインタビューで、もうコンピュータは研究されつくしているので、コンピュータではなく生物学に進むよう息子さんに言っているが、それから10年たって、どう思うか?)

 考えは同じです。コンピュータの世界では予測できないような革新的なことは何も起きていません。一番最近の重要なものはインターネットだと思いますが、それは1999年にもありました。すべてが発展し、個々のコンピュータのスピードは格段に速くなっていますが、でも何が違うでしょう?

 

・(ハードウェアを極度に抽象化したプログラミングも楽しいのでは?)

 やみつきにさせるものがありますが、自分の子どもに入り込むように言おうとは思わないでしょう。変わったのだと思います。私が年取っただけかもしれませんが、ほかのレイヤの上にある、ほかのレイヤの上に、さらに別なレイヤを作るだけというのでは、たとえば決定性有限オートマトンを作るときの利点は得られないように思います。必要に応じて新しいアルゴリズムは時と共にどんどん複雑になっていきます。1つの新しいアルゴリズムが、他の50個の小さなアルゴリズムに依存しているというような。私が若かったころは、そういった小さなアルゴリズムに取り組んでいて、それは楽しいものでした。それ自体で理解できるものでした。細かく場合分けし、それぞれの場合は聞いたことはあるけれどよく知らないアルゴリズムによって解かれるというような、会計みたいな仕事をする必要はありませんでした。だから変わったのです。変わっていると本当に思っており、その多くは、時と共にすべて階層化され、階層を扱うようになったことによるのだと思います。私は階層を理解するには頑固すぎるのかもしれません。

#しびれるねぇ(ピングドラム)。

 

第13章 Fran Allen

・(最後にプログラミングしたのはいつ?)

 かなり昔のことです。Cが現れたころにやめてしまいました。あれは大きな一撃でした。私たちは最適化や変換について非常に進んでいました。大きな問題を1つひとつ解決していました。Cが現れたとき、SIGPLANのコンパイラの会議の1つで、Cを支持するベル研のスィーブ・ジョンソンと、当時私のやっていた自動最適化のプロジェクトにいたビル・ハリソンが議論をしました。

 スティーブはプログラマが自分でやるからもはやオプティマイザを作る必要はないと主張しました。最適化はプログラマの問題なのだと。Cの設計の動機になったのは、高級言語では解決できなかった3つの問題です。1つは割り込みを扱うことです。もう1つはリソースのスケジューリングで、マシンのかわりにキューにあるプロセスのスケジューリングをするということです。3つ目はメモリ割り当てです。高級言語からはできませんでした。それがCの言い分でした。

#どれも現在では当てはまらない。私見では、Javaレベルの高級言語による素朴な超循環評価器が、Cで実装されキンキンに最適化されたVMよりも速くなる日は10年以内にやってくる。ハードウェアのアーキテクチャが複雑になるにつれて、手作業でのアドホックな最適化はますます不利になる。そしてCPUクロックの向上が止まった現在、ハードウェアのアーキテクチャは複雑さを増す方向に向かっている。GPUやマルチコアなど。

 

・1960年までには、見事な言語のリストができていました。Lisp、APL、Fortran、COBOL、Algol 60。Cよりも高級な言語です。Cが開発されて、私たちは大きく後退したのです。Cは自動最適化、自動並列化、高級言語からマシンへの自動的なマッピングといった私たちの能力を壊してしまいました。これはコンパイラが大学でもはや基本的に教えられなくなった理由の1つです。

 

・Cのような言語は問題の解決法を細かく決めすぎてしまうからです。そういう言語が、学問としてのコンピュータサイエンスを壊してしまったのです。

 (中略)

根本にある問題はデータの場所を指定するということです。ほかの言語を見てもらえば、データの場所や、それをどう動かすか、マシンのどこに置くかということまで指定しようとはしないのが分かるでしょう。どの時点でも、究極的には値が問題にされていたのです。

 

・私たちが最適化の世界で計算についてやってきたことが、データについても行えるチャンスがあると思っています。私たちはデータをあまりうまく管理していません。データを自動的に管理する方法、一緒に使われるデータにローカル性を確立するための良い方法を私たちは持っていないのです。

 とてもエキサイティングな研究の流れがたくさんあります。しかし欠けているのは、もっと大きく大胆なコンセプトです。多くのことは既存の枠組みや現在の考え方の範囲内で起きています。一夜にして様相を変えるようなものではありません。何百万行というコードがあります。しかし私たちは「これはここでやる、あれはあそこでやる」という境界を壊そうと試み始める必要があります。

 

・現在我々は基本的にリファレンスを使ってやっています。ハードウェアによって、あるいは下にあるオペレーティングシステムやサポートシステムによって動かされています。そしてリファレンスは多くの場合要素のレベルです。

 

・(つまり、構造体や配列の中を指すポインタを持てるというような意味で?)

 ええ、要素の中にです。そしてそれが、ハードウェアやアーキテクチャのプロトコルに応じて、値をその使われる計算の部分へと運ぶのです。

 しかし別な方法として、データの相対的な位置を最適化の対象として場所を整理することもできるでしょう。ある計算には良いことが別の計算にはよくないということも出てくるでしょう。ある整理方法が、マトリックスのようなシンプルなものでさえ、違ったやり方でアクセスした場合にはまずいものになり得ます。だからアクセスの順序と場所の組み合わせによるのです。アーキテクチャやハードウェアにおける仕事が必要になるかもしれませんが、リファレンスやアドレッシングの機能の一部をハードウェア自体に任せるようにすれば、実現できると思います。データがメモリに来る時点で非常に多くの変換を行えるようなマシンがあります。マッピングをそこで行えるのです。

 

・私たちに必要なのはもっと高級な言語やドメイン固有言語、そして開発のための本当に良い方法です。

 

第14章 Bernie Cosell

・私が信じていたことが2つあって、それはとても有効に働いたのですが、プログラムは意味がなければならないということと、本質的に難しい問題というのはごくわずかだということです。すごく難しそうに見えるのは、おそらくはしなければならないことをすっかり理解してはおらず、コードが正しそうに見えるまでハンマーでたたくプログラマによる結果なのです。

 

・大学によっては9月から5月まで続く2期の授業があって、最初に非常に難しいプログラミングの問題に取り組ませていました。それからいくつもの難問を片付けた後、4月にふたたびそのプログラムに取り組ませるのですが、そのことは最初の時点では言わずにおくのです。そこで意図していたのは、ほんの6ケ月前に完璧に理解したと思っていたことを思い出すのがいかに難しいものか驚かせるということです。

 

・世の中には、たぶん私を含め、良いプログラマがいて、良いCのプログラムを書くことができます。しかしそれは本来あるべきよりも難しいのです。現代的な環境ではより難しく、それは環境自体が難しくなっているからです。Cの弱さが悪用されたり見落とされたりする可能性のある、注意しなければならない部分が量的に増えています。

 

 Javaは正しくない感じがします。私の古い反射神経がそう言っています。Javaは権威主義的すぎます。これはPerlが良いと感じられる理由の1つです。安全でチェックされていますが、とても多角的であり、私の中の芸術家的な部分を解放して、物事を明確に表現し正しいやり方を考えられるようにしてくれます。ある自由を手にできるのです。

 私が最初にJavaをいじったとき、まだ小さな言語だったときのことですが、「ああ、これはまた例によって、あんまりできのよくないプログラマを助けようと、できることを制限してまっすぐな細い道を歩かせる言語だな」と思いました。しかし私たちはそういうのが正しい地点に来ているのかもしれません。1パーセントか2パーセントのプログラマだけがすごい作品を作り出せる優れた柔軟な言語を使うには、世界はあまりに危険な場所になってしまったのかもしれません。

 

第15章 Donald Knuth

・(自分の本で取り上げるアルゴリズムについて)nが2の100万乗より大きいときにlog log nの割合だけ速くなるデータ構造なんかは取り入れません。そういうことをやっている論文がすごくたくさんあります。コンピュータが神のようであるとしたら、原理的にはより速いアルゴリズムが得られるという、一種のゲームをしているのです。

 

 問題は、ライブラリを自分で書けないなら、やることはライブラリを呼び出すことだけになり、プログラミングは楽しいものではなくなるということです。プログラミングの仕事がパラメタの正しい組み合わせを見つけるだけということになれば、すごくつまらない話で、そんなことを職業にしたい人がいるでしょうか?

 再利用可能ソフトウェアが過度に強調されていて、それは箱を開けて中に何があるか覗くことが決してない世界です。そんなブラックボックスがあるのは結構ですが、ほとんどの場合箱の中身を見ればそれを改善することができるし、箱の中身を一度知ればよりうまく使えるようになるのです。しかしそうする代わりに人々はあらゆるものの周りに閉じた覆いをつけ、世界のプログラマに閉じたものを渡し、プログラマはそれをいじることが許されないのです。彼らにできるのは組み立てることだけです。それでこのサブルーチンを呼ぶときはx0, y0, x1, y1を渡し、こっちのサブルーチンを呼ぶときはx0, x1, y0, y1を渡すというようなことを暗記します。それを正しくやるのが仕事というわけです。

 

・私にとってプログラミング言語におけるもっとも大きな革命は、C言語におけるポインタの使用です。ある程度複雑なデータ構造があるとき、構造のある部分と別な部分をつなぐ必要があり、それは様々な方法で高級言語に取り入れられています。たとえばアントニー・ホーアはすごくきれいなシステムを持っていました。しかしC言語で追加されたものは、最初私はそれが大きな間違いだと思っていましたが、後になってすごく気に入りました。つまりxがポインタのとき、x+1はxの1バイト後ということではなく、xが何へのポインタかに応じてxの1つ先のノードを指すということです。xが大きなノードを指している場合には、x+1は大きくジャンプすることになります。xが小さなのを指していればx+1は少しだけ移動することになります。私にはこれが記法におけるもっとも目覚ましい進歩に思えます。

#いかにも「Cは遅すぎる、アセンブリ言語で書け」と言ってのけた人らしい意見。

 

 ポインタは今では私のお気に入りではなくなりました。私がここに持っているような64ビットコンピュータでは、マシンの能力を本当に生かそうと思うなら、ポインタを使わないほうがよいのです。というのも、このマシンは64ビットレジスタを持っているのにRAMは2GBしかありません。だからポインタは上位32ビットを決して使うことがありません。それでもポインタを使うたびに64ビットを消費し、データ構造のサイズが倍になってしまいます。さらに悪いのは、それがキャッシュを使うということで、キャッシュの半分が無駄になってしまいます。キャッシュはとても高価だというのに。

 だからプログラムを本当に限界まで持っていこうと思うなら、ポインタの代わりに配列を使う必要があります。複雑なマクロを書いて、それがポインタを使っているように見えるようにしているのです。これはある意味小さなことで、やがて廃れていくことでしょう。しかし私にとっては、ポインタは低レベルの記法における重要なアイデアだったのです。私がコードを書いたりデバッグしたりするときには、今でもトンプソンとリッチーに感謝の念を抱きます。どちらが考え出したのか知りませんが。

#「だからポインタは上位32ビットを決して使うことがありません」って、ファイルのmmapは?

 

・アルゴリズムやデータ構造のコミュニティにおけるトレンドで気に入らないのは、彼らが「バロック調」とでも言うしかないデータ構造を追求していることです。それは精緻で巧妙で、知的挑戦という点では賞賛するほかないのですが、不毛なものです。生活につながっていません。別世界に生きているのです。それは結構な世界で、それ自体の組織を持ち、友好的でいい人たちですが、個人的にはあまり魅力を感じないし、実用とは結びついていません。

 

・誰かほかの人の考え方の中に浸って、そのボキャブラリや記法を解読できる能力はとても重要です。その人たちの考え方や発見した方法を理解できれば、自分で発見をするときに役立ちます。私は過去に優れた人々が言ったことが書かれた文献をよく読みます。今日の観衆からすると変わった方法で表現されているかもしれませんが、彼らの記法を通して彼らの考えを捉えようとするのは価値あることです。

Posted by hajime at 2012年01月19日 16:58
Comments
Post a comment






Remember personal info?