走るものが正本
仕様があれば、あとはコードに変換するだけだ。そう言われることがある。
外から見ると、プログラミングは確かにそう見える。仕様書が入力で、コードが出力。その間を埋める作業がプログラミングだとすれば、変換が自動化された時点で、仕事はほとんど残らない。
推論としては筋が通っている。実際、決まったことを決まった形に書き写す仕事は、少しずつ減っている。
私に見えている景色は、それとは少し違う。外から見えているのは変換の部分だけで、作る難しさの多くは、その手前、仕様がまだ存在しないところにある。
仕様が固定されているなら、作ることはむしろ易しい。それに従えばいいし、それが絶対だから迷わない。何を作るか、どこまでやるかは、すでに決まっている。制約がそこにある。
ソフトウェアを作る難しさは、多くの場合、その制約がないところにある。何を作るのか。どこまでやるのか。何を捨てるのか。それを決めなければならない。そして、それは作る前には決められない。
仮の制約を足場として置くことはできるし、私もそうする。けれど、それは走らせて確かめるための仮説であって、正本ではない。
何かを作るとき、最初に思い描いたゴールにそのままたどり着いたことは、ほとんどない。いつも作りながら動かしている。特別な出来事として思い出すのが難しいくらいに。
ひとつ挙げるなら、いま作っているソフトウェアのことがある。最初はワークフローのような画面をしていた。表現したかったのは継続性で、流れとして並べると、それはうまく見えた。
ところが、実際にデータを入力しようとした途端、違うとわかった。流れとして眺めるにはいい。けれど、書き込んだり直したりするには、ごく普通の一覧のほうがずっと扱いやすい。ワークフローは見るための形で、手を入れるための形ではなかった。
継続性を表現したい、という意図は今も変わっていない。変わったのは形のほうだ。そしてその形は、作って、触ってみるまで、わからなかった。
作ってみるまでわからない。それは、作る前に書いた仕様が、作ったあとには古くなっているということでもある。
では、何が正しいのか。
不具合も含めて、走っているものが事実だ、と私は思う。コードが正本なのは、それが正しいからではない。実際に走るからだ。バグがあっても、それはそのシステムが現にそう振る舞っているという事実で、使う人が触れているのはその振る舞いだ。仕様書はどれだけ丁寧に書かれていても、事実になる回路を持っていない。それで何かが動くわけではないから、正しいと言い切ることができない。
では、意図はどこにあるのか。私は、作っている人の中にあると思う。コードも仕様書も、その意図を外に書き出したものだ。違うのは、書き出される順番だ。作りながら何かを見つけたとき、それが最初に現れるのはコードのほうで、仕様書に届くのはそのあとになる。
だとすれば、仕様書はコードから起こせばいい。いちばん新しい意図が書き込まれているのはコードで、仕様書はその後追いの要約になる。少し遅れていても、走っている正本には何の害もない。
向きを逆にすると、話が変わる。仕様書を先に固めてコードを起こそうとすると、意図を人の外に出して固定し、あとは変換で済ませようとすることになる。そうすると、作りながら見つけたものの行き場がなくなる。見つけたものを取り込めなければ、作っているものは育たない。最初に思い描けた以上のものには、ならない。
仕様が先にあるように見える世界もある。プロトコルや規格だ。複数の実装が互いに通じ合うためには、どの実装でもなく、仕様が基準にならなければならない。
けれど、その始まりをたどると、そこにもまず走るコードがある。Web の HTTP は Tim Berners-Lee の実装が先にあり、仕様は、すでに広く使われていた振る舞いを後から書き起こしたものだった。インターネットの標準化では、独立した実装が実際に互いに動くことが、仕様を成熟させる条件とされてきた。HTML も、ブラウザが実際にどう動いているかを調べ、その振る舞いを仕様に書き戻している。設計を先に固めようとした OSI は、すでに走っていた TCP/IP に道を譲った。
固定された仕様に従って作るのが易しいのは、制約を見つける作業がすでに済んでいるからだ。誰かが走らせ、確かめ、合意した。その結晶を受け取っている。一度固まれば、多くの実装がそれに寄りかかるので、簡単には動かせない。けれどそれは、仕様が出発点だったということではない。
約束事でさえ、仕様から始まるわけではない。
最初に制約を決めてしまえば、ゴールが動くことは失敗になる。手戻り、仕様変更、見積もりの狂い。
私にとっては逆だ。ゴールが動くのは、何かが見つかった証拠だと思う。ワークフローの画面を一覧に変えたとき、継続性を表現したいという意図は残った。動いたのは形のほうで、動いたあとの形のほうが、そのシステムにはまるべき形に近い。
だから私は、走るものを正本に置く。仕様はそこから起こす。制約は先に決めるものではなく、作りながら見つけるものだから。