Island Life

2005/01/23

半年くらい前に Paulの反オブジェクト指向のメモ翻訳していたのを 公開するのをすっかり忘れてた。 Jonathan Reesのメッセージの方の 公開をちょっと待つ事情があって、待ってるうちに忘却の彼方に 消えてしまっていたのだった。

Tags: PaulGraham, 翻訳

2005/01/22

Paul Grahamのエッセイの新作が出てた。ひさしぶりに熱い内容だったので 一気に訳してしまった。

自分の高校時代を振り返ってみると、たぶん半分くらいは、 いや3/4くらいは、本当に好きなことをやっていたと思う(その大半は 演劇部だった)。でもどこかでブレーキをかけていたところがあった (「こんなに忙しくて大変だ」って思ってたからね。その時の自分に 数年後のスケジュールを教えたらどう思ってただろう)。 Paulがいうように、高校でできることの大部分はそれ以降の本物の仕事に比べたら 誤差くらいのものなんだから、遠慮無しにやってれば良かった。 今、時を遡ってあの時の自分に会えるなら、絶対後悔しないから もっとやれ、とハッパをかけるだろう。

でも、人生の到達点はそれまでの積分なんだから、同じアドバイスが どの時点でも有効なはずだ。やりたいことはたくさんある。それなら、 絶対後悔しないから、貪欲に、遠慮せずにやればいい。

Tags: PaulGraham, 翻訳

2005/01/17

yomoyomoさんとこより、 メンテナンス可能なコードの書き方、およびその関連で Great Programmers。 良いコードとは、つまるところ適切なカプセル化とユニットテストにある、という 主張には基本的に同意。

ただ、「カプセル化 encapsulation」はオブジェクト指向界隈で「実装の隠蔽」 の意味で使われることが多いような気がする () ので個人的には避けたい用語だ。本当に重要なのは、(a)あるコードの変更が 影響を及ぼす範囲が容易に確定できること、(b)あるコードの意味に影響を 与える範囲が容易に確定できること (両者は同じことの表と裏だが、実際に コードをいじっている時には両方を考慮している)、であるはずだ。 私はこれをモジュラリティと呼んでいる。

実装の隠蔽はモジュラリティを実現する一つのツールだが、必要でも十分でもない。 実装を完全に隠蔽してもモジュラリティの低いコードはいくらでも書けるし、

実装を隠蔽しないでもモジュラリティの高いコードは書ける。うっかりミスを 防ぐ意味では有用かもしれない、という程度だと思う。 しかも、本当に厄介なバグは実装の隠蔽だけでは防げないような種類のものだ。

モジュラリティにとってより重要なのは、状態の管理だ。 何かが状態を持ち、そのふるまいが状態によって変化する場合、 あるコードの意味はそのコードの静的なスコープだけでなく、 対象となるものの状態にも依存する。静的に確定できるスコープの 外でそのものの状態が勝手に変えられてしまうと、もはやコードの 見た目を信頼することができない。

実装の隠蔽によって状態をさわれる箇所を限定することでこの問題は ある程度軽減できるが、それは対症療法にすぎない。例えばpublicな getterとsetterを用意してインスタンス変数を隠蔽することは この問題に対してほとんど何の解決にもなっていない。 もう少しソフィスティケートされたAPIを用意したとしても、 実装者の想定した方法以外でオブジェクトの状態を変えるパスがどこかに 存在する限り、問題は残る。

本当の問題は、状態を持つことそのものにある。ただ、現実の世界が ステートフルである以上、そことつき合うプログラムもまた状態を 持たざるを得ない。状態という猛獣をいかに飼い慣らすかという視点で 設計を行うべきだろう。実装の隠蔽も、状態を常に実装者の想定に 従うように管理するという目的で使われる場合には、有用だ。 もっとも、状態遷移が明示的にAPIの一部になっていることの方が重要で、 カプセル化はその安全ネットを提供するにすぎないと思うが。

形式的に状態を制御して扱えるようにするには、現実的には 静的型が必須のように思える。(Schemeでモナドを書いても Haskellのように綺麗にならない。) ただ、そこまでやらなくても いくつかのアドホックなテクニックを使うことで、 かなり安全に状態を制御することはできるだろう。

Tag: Programming

2005/01/10

言語のコアが単純であることの効用

「良いデザインは再デザインである」(Paul Graham)---これは言語そのものの デザインではなく、処理系のデザインにも言える。とりあえず動くバージョンを 作って、それを実際のアプリケーションで使ってみて、そこでの観察をもとに 処理系を改善してゆく。このサイクルを多く回せば回すほど、実装は良いものに なってゆくはずだ。また、色々なアイディアを思い付く端から実装してみて 試してみる。それが簡単であればあるほど、その中から実際に使えるアイディアを 拾いあげやすくなる。

だとすれば、処理系のリライトがやりやすい方が、良い実装へと収束しやすいだろう。 言語が、少数のコア要素と、その上に構築される要素からなっていれば、 言語のフルスペックを保ったまま、コア部分やその上の各コンポーネントを独立に 差し替えて行くことができる。これは処理系をごっそり書き直すのに比べて ずっと敷居が低い。

(コア要素の上に構築する要素は必ずしも実行時のレイヤリング、つまり ライブラリを言語のコアオペレータで書くこと、を意味しない。 構文糖衣をメタプログラミングで追加するような場合、レイヤリングは コンパイル時のもので、実行時性能には影響を及ぼさない)

もっとも最初から全てを考慮したインタフェースをモジュール間に作るのは 難しい。やってみないとわからないことがたくさんあるからだ。 時には、インタフェースを保つために変更する側のモジュールに醜いスタブを 噛ます必要も出てくる。ただ、対応するモジュールも十分に速く改善できて、 結果としてスタブがすぐに外せるのなら、大した問題ではないだろう。

最適化はモジュラリティとぶつかる場合がある。モジュラリティは一般化を指向するのに、 最適化は特殊化を指向するからだ。せっかくきれいにレイヤを切ってモジュール化 してあっても、最適化は複数のレイヤに変更を強いる場合が多い。 これについては、最適化をオプショナルにしておくこと (何かのフラグで切ることができるようにしとく)くらいしか思いつかんなあ。

Tag: Programming

2005/01/08

TPOSSCON 2005. へー、Bruce Perensがハワイに来るんだ。 ちょっとのぞいてみようかな。

Tag: Conference

More entries ...