今回からしばらく「Comparators」と題した読み物を書かせてもらうことになりました。よく似た、あるいは相反する2つのアイデアを見比べたら何かが見えてこないか。そんなもくろみで書きたいと思っています。
今回のComparator(比較演算子)はこの2つ、HackabilityとHackinessです(図1)。どちらも耳慣れない言葉かもしれません。
Hackability
Hackabilityとは、ソフトウェアやシステムの性質、その対象が「ハックできること」や「ハックしやすいこと」を意味します。ハックと言ってもセキュリティホールを攻撃するほうではなく、コードを書いて遊ぶほうです。
「あの会社から出てきた新しいサービス、スクリーンキャストを見たよ。デザインはカッコいいね。けっこう遊べそう?」「いやー、SDKどころかAPIもないからHackabilityはいまいちですね。ページもJavaScriptが多くてスクレイピングに一苦労でしたよ」なんて風に使います。
Hackiness
対するHackinessは形容詞Hackyを名詞化したもので、これもソフトウェアの性質を表す言葉です。コードやソフトウェアが「まるっきりハック」であること、やっつけ仕事なコードを評するときに使います。
「あの仕事やっておきましたよー。とりあえず動いています」「おっ!早いね……ってこれすげえHackyじゃん。なんですかこの山のように差し込まれたif文は。こっちはサードパーティのライブラリに手を入れちゃってるし。このパラメータを変えて再起動すると……。ああ、やっぱりエラー。動くのはわかったから、あとはちゃんと整理しないとね」
WebのHackability
話をHackabilityに戻しましょう。Hackabilityを持つシステムの代表例はWebです。Webの基盤技術はHackabilityの高いデザインに従っています。
まずプロトコルやデータが単純なテキストであるため、簡単に中身を覗くことができます。プロトコルの詳しい知識なしに見よう見まねでHTMLやHTTPを読み書きした経験は、誰にでもあるのではないでしょうか。バイナリ形式のデータ相手にこうはいきません。
WebブラウザもWebのHackabilityを手助けしています。たとえばメニューからは「ページのソースを表示」できます。表示したページに対しデバッガを起動するのも簡単です。ユーザが簡単にデバッグできるアプリケーションなんて、ほかにどれだけあるでしょうか。Webの外ではデバッガすらなかなかすぐには使えません。しかしWebでは開発者が何もしなくてもブラウザが勝手にWebアプリケーションをHackableにしてしまいます。むしろアプリケーションをHackableでなくするほうが一苦労です。
Webが分散システムである点もHackabilityを支えています。WebブラウザとWebサーバは別のプロセスとして動いていますから、プログラム同士は必ず通信をします。そしてブラウザとサーバの通信を横取りしたり、サーバ相手にブラウザのフリをするのはとても簡単です。
読み書きしやすいテキスト形式、割り込みやすい分散アーキテクチャ、デバッガの遍在。そのほかにも標準化され互換性を重んじるAPIなど、さまざまな性質がWebのHackabilityを支えています。
プラットフォームとHackability
WebのHackabilityは偶然の産物ではありません。黎明期(れいめいき)、Webの設計者たちは、ハイパーテキストのアイデアに魅力を感じた人々に互換性のあるソフトウェアを作ってほしいと願いました。これはインターネットがネットワークソフトウェアにもたらしたHackabilityを、インターネットの上で動くアプリケーションに持ち込もうとする大きな流れの一部でもありました。
Webやインターネットのように、振る舞いを公開してプログラム可能にしたシステムやソフトウェアをプラットフォームと呼びます。プラットフォームという言葉はさまざまな意味で使われはじめていますが、ここではほかのソフトウェアに向けて振る舞いを明らかにしているもの、具体的にはプロトコルやAPIを公開したソフトウェアのことを指すものとして話を進めましょう。WindowsやLinuxのようなOSや、Facebookのような一部のWeb上のサービスなどがプラットフォームとしてよく知られています。
Hackabilityの程度
プラットフォームにはHackabilityがあります。私たち開発者のコードからAPIを通じて呼び出すことができるからです。とはいえ、世の中のプラットフォームがどれも等しくHackableであると言えるのでしょうか。明らかにそんなことはありません。
プラットフォームが開発者にアクセスを許している情報や機能は、APIによって制限されています。たとえばAPIがすべてのデータにアクセスできるWeb上のサービスはほとんどありません。たとえ同じ分野のサービスでも、APIで公開されているデータの範囲はさまざまです。たとえばOSで考えてみると、デスクトップOSの多くは開発者がカーネルモジュールやドライバを書くことができました。でもスマートフォン向けOSでそれを許しているものは限られています。
WebのサービスやOSなど、同じ分野に属するプラットフォーム同士を比べればHackabilityの個体差は明らかです。つまりHackabilityは白黒はっきりした真偽値ではなく、濃淡のある連続した概念、程度の問題なのです。プラットフォームのHackabilityは機能やデータという軸の上に分布しています。アクセスできるデータや機能が多いほどHackabilityは高くなります。これらさまざまなプラットフォームと比べてみると、Webというプラットフォームに備わったHackabilityの高さに改めて気づくのではないでしょうか。
オープンソースのHackability
オープンソースライセンスは、コードやデザインではなくライセンスによってソフトウェアのHackabilityを実現しました。オープンソースのソフトウェアはほとんど定義からHackableです。ソースコードが公開され改変が認められている以上、私たちがそれをどうハックしようが自由なわけですから。
では、オープンソースのソフトウェアはどれも等しくHackableなのでしょうか。それとも濃淡があるのでしょうか。たとえばEclipseとLinuxとjQuery Mobileが同じくらいハックしやすいものか想像してみましょう。……とてもそうは思えませんよね。一方で、プラットフォームのHackabilityを議論するときに使った評価軸、具体的には機能やデータへのアクセス度合いを持ち出すのもどこかピントがずれています。
プラットフォームのHackabilityに向けた視線は、プラットフォームの上で書くコードの遊びやすさや自由度を気にしていました。一方オープンソースのHackabilityを評価するとき気になるのは、ソフトウェアそれ自体、コードの中でのやりやすさです。気にしていることが違いますから、同じようには比べられません。
WebKitに見るHackabilityの指標
では、コードの中のHackabilityは何が左右するのでしょうか。
オープンソースのHTMLレンダリングエンジンWebKitは、プロジェクトのゴールの一つにHackabilityを挙げています。プロジェクトに大きな判断が求められる議論では、このゴールがたびたび引き合いに出されます。
あるときWebKitにユニットテスト用のフレームワークを追加しようと提案があり、やはりHackabilityが俎上(そじょう)に載りました。サードパーティのテスティングフレームワークを採用するならHackableなものを選ぶべきだというわけです。議論されたHackabilityの指標は主に次の2つでした。
- ① コードを書き換えたら、差分は本家に取り込んでもらえるのか?
- ② 都合に合わせて変更できるわかりやすいコードなのか?
これはオープンソースにおけるHackabilityの特徴をよくとらえています。つまりオープンソースのHackabilityには①のようなプロジェクトの文化的、政治的側面と、②のようなコードにまつわる側面があるのです。変更しやすい、そして変更が取り込まれやすいオープンソースのソフトウェアほどHackableである。腑に落ちる説明ではないでしょうか。
ソフトウェアの保守性とHackiness
変更を加えやすいコードほどHackableなのは、何もオープンソースに限りません。コードの中に手を加えてハックをするなら、ライセンスにかかわらず書き換えやすいに越したことはないからです。読みやすく変更しやすい、要するに保守性の高いコードほどHackabilityは高くなります。
……本当でしょうか?
Hackabilityを気にするとき、私たちがやりたいのは開発の続きではありません。ハックです。私たちはそのコードにHackinessの高い変更を加えたいのです。私たちはふとしたアイデアを試したいのです。あるいはちょっとした不足を埋めたいのです。あるいはただ、それがどんな風に動くのか、少しだけ壊して確かめたいだけなのです。寝る前に、昼休みに、週末に、手早く、気楽にいじりたいのです。綿密に組み立てられ、冗長性を排し、すべての知識をコードに埋め込もうと意気込んで書かれた「保守性に優れたソースコード」は、はたしてこうしたハックを許すでしょうか。
しなやかさとおおらかさ
考えぬかれた洗練は、それ自体が欠点にもなります。洗練されたコードに手を加えようと思ったら、プログラマは元の開発者と同じくらい考え抜き、洗練された設計でコードを書かなければいけないからです。Eric Evansはこの洗練を「しなやかな設計」と呼びました[1]。
しなやかさはプロジェクトを通じた学びの証です。新参開発者がもとの書き手と同じ険しい学びのプロセスを経る必要はありません。しかし、少なくともその成果を学ぶ必要はあります。精巧に組み立てられた抽象には型システムや自己検証といった防御が施され、安易なやっつけ仕事を許さないからです。私たちは丁寧にコードを読み、編みあげられた意図を解きほどく必要があります。
しなやかなコードを読むのは楽しいものですが、ハックの下準備としては大げさ過ぎます。ハックをする私たちは開発チームの新メンバーというわけではありません。ふらりと遊びにきた通りすがりです。宴会のない土曜の夜、コーヒーを淹れてエディタを立ち上げ、チェックアウトしておいたコードからgrepとデバッガを頼りに目当てとなる場所の当たりをつけ、適当にブランチを作りがちゃがちゃと書き換える。ハックとはそんな風であってほしいと思いませんか。
だとしたら、Hackabilityの高いコードには何が必要なのでしょう。私はこんな風に考えています。
しなやかさを支えるのが抽象を貫く「規律」だとしたら、Hackabilityを支えるのはHackinessを受け入れる「おおらかさ」である。
ちょっとくらいヘンなヤツ(ハック)が紛れ込んでも大目に見ることのできる「おおらかな」コードほど、私たちはHackableだと感じるでしょう。たぶんそうしたコードにはリフレクションや型システム、知られざるシステムコールなどを駆使する粋なマジックなんてありません。テストはあるけれど適当で、ときどき驚くようなリグレッションが見つかるでしょう。そして誰かの書いたHackyなコードがあちこちに顔を出して私たちを驚かすでしょう。
Hackableなコードはどこかおおざっぱで、ありていに言えば大したことのないコードに見えます。けれどそもそも、そのコードには私たちにハックしようと思わせる何かがあったはずです。つまりコード以前に私たちの気を引くところがあるソフトウェアなのです。そして中を覗きこんだ私たちを迎え入れてくれたのがHackinessだったのです。
Hackinessの限界
通りがかりにやさしいHackinessを応援したい一方で、そのおおらかさが持つ限界も認めないわけにはいきません。
Hackinessはコードを引き寄せます。ハックによって書かれたコードが取り込まれたソースツリーはどんどん成長します。凝った抽象のない単純なコードに雑多な追加が積み重なり、熟読なしに入り込めた敷居の低いコードは、いつか人波のごったがえす、誰の手にも負えない割れ窓だらけのスラムに姿を変えます。あちこちで諍(いさか)いが目立ち始めます。テストが真っ赤のままリリースに踏み切って阿鼻叫喚(あびきょうかん)が巻き起こり、現場にかけつけたあなたは言葉を失います。いつの間にこんなことになってしまったんだ……。
歴史あるソフトウェアにはよくある光景です。ハックは時が経つと負債に姿を変えます。どこかでしなやかさを取り戻さない限り、そのソフトウェアは複雑さに足を取られ進めなくなるのです。そんなとき、何か打つ手はあるのでしょうか。
HackinessからHackabilityへ
プラットフォームのHackabilityを思い出してください。それは、ソフトウェアの「上で」行われる遊びでした。コードの「中に」負債として積み重なったハックをよく見ると、実は「上に」持ちあげられるものが多く混じっていることに気がつきます。しかも、それら「上向き」のハックが現れる場所はコードの一部に偏っていませんか。呪われた1,000行に目を凝らせば、10回分の100行ハックが見えてくるのではないでしょうか。
ハックのアイデア、ソフトウェアに求める新しい機能は、案外似通ったものになりがちです。したがって積み重なったハックはソフトウェアに機能追加の柔軟性を求めるシグナルだと解釈できます。「ここはもっと汎用的に作ってくれ」、一連のハックはそう知らせます。コードにしなやかさを迎え入れる日がきました。リファクタリングをしてAPIを作りましょう。そして呪われた1,000行を、ごっそりAPIの「上に」押し出しましょう。私たちのソフトウェアをハックの塊からハックのプラットフォームへと成長させるのです。
あちこちに溢れていたハックがAPIの上に歩み去ると、コードからは秩序と入れ替わりにHackinessが失われます。このときある種の喪失感がよぎります。遊び心が、冒険心が失われた。そんな気持ちです。
でも悲しむことはありません。巣立っていったHackinessたちは、私たちの上で新たな楽しみを見いだすでしょう。そこではまた新しい遊びが、ハックが産まれることでしょう。規律に追い立てられしなやかなまま育った品の良いソフトウェアがこうしたハックをはぐくむことは多くありません。一方Hackinessを内包したおおらかなソフトウェアはハックを育て、自身も段々とHackabilityを身につけていきます。バグだ、パッチだ、フォークだと騒がしい末裔(まつえい)たちに囲まれ苦笑いする。それがきっと、私たちの望んだ成熟の姿なのです。