八発白中

技術ブログ、改め雑記

Clack、裏イントロダクション

先日、ClackのTutorialの更新を始めた。ただ、公式チュートリアルということもあって、あまり熱狂的なことも書きづらい。他のプロジェクトの名前を挙げて比較するのも行儀が悪い。そんなことを意識しながら書いたので、割とよくある平凡な文章に落ち着いてしまった。

とは言え、このイントロダクションを見てClack始めたい!と思う人も少なかろうと思う。なので、非公式なイントロダクションをここに書く。

ライブラリ環境の問題点

去年の正月休みはほとんどClackを作っていた。Clackは当初とても小さなものだったけど、開発開始から最初のαリリースまで1ヶ月ほどかかった。それには理由がある。

当時思っていたことは、Common Lispのライブラリ環境の整備はとても遅れているということだった。少ないだけでなく、中には特定の処理系/OSでしか動かないものもあったり *1、ドキュメントがない、その上コードも読めない、みたいなものが多かった。

そんな中で「俺が使いたいライブラリがないから作った」みたいに闇雲にライブラリを増やしても意味がない。そのため、Clackは過去のライブラリを反面教師に多くのことに留意して開発された。

読みやすさ

まず、誰にでも読めるコードを心がけた。本当に。偏執的なまでに。

もちろん、自分だけが読めても意味がない。コードの読みやすさは客観的な指標であるべきで、本人が書いているときは「美しい!」と思って書いてたとしても、他の人や1ヶ月後の自分が見たら「意味不明」って思うかもしれない。

そこで知っておかなければならないのは、読む人間は僕と違ってClackのすべてのコードを知っているわけではないということだった。依存関係は極力少なく、明確にした。「このコードを読むにはこのパッケージのこの関数も知っておく必要がある」ということを明示するために、すべてのdefpackageには:useではなく:import-fromが使われた。

Clackは一気に書き下されて完成したわけじゃない。コードのさまざまな部分々々を切り出して、それが何を表しているかが自明となるように注意が払われた。Tomohiro Matsuyamaには多くの意見をもらいながら、一度書かれたコードは何度も修正が繰り返され、よりよい形に落ち着くまで十分な改善がなされた。興味深いことは、その過程で使われていたマクロの多くは排除されたことだ。

マクロの対比としてWeblocksを例に挙げる*2。Weblocksで重要なコンポーネントの1つに「ウィジェット」がある。僕はこれがどのような役割があるのか本当にはわからない。ただ、Weblocksを使うにはこれが必要らしい、ということだけ知っている。

ウィジェット」を定義するには「defwidget」を使う。ただ、これが本当に何をするかはわからない。マクロだからだ。その形から、実際はただdefclassに親クラスやメタクラスを埋め込むものだと予想できるが、それにどういった意味があるかはユーザは間接的にしか知ることができない。

実を言うと、Clackの最初期の実装も似たようなものになっていた。これがCommon Lispでは標準的なAPIの提供法だからだ。けれど、それらは徐々に噛み砕かれ、最後にはCLOSクラスをそのまま提供するまでになった。ClackのComponentを定義するには、<component>クラスを継承したクラスを定義するだけで良い。この程度のことにdefcomponentなんてマクロはないほうがいい。

ドキュメント整備

さらに、僕はコードが読みやすいだけでは不十分ということも知っていた。僕にとって他人のコードを読むのは苦痛だった。コードを読んでいるときは、大抵ドキュメントが不十分で、何かわからないことがあるから仕方なく読む、という状況だった。僕は、他人がClackを見て同じ思いをするのはとても耐え難いことだと感じていた。

これを回避するため、Clackは公開時にはすべてドキュメント化されている必要があると考えた。去年の今頃は、Clackのαリリースに向けてほとんどドキュメントの整備ばかりしていた。これにはおよそ2週間ほどかかった。ほとんど動いているプロダクトを抱えて、早く発表したい気持ちを抑えての2週間だ。最初に言ったけれど、ただ作るだけでは意味がないということを僕はよく知っていた。それが使われなきゃ。そのドキュメントはリリースごとに随時更新され、http://clacklisp.org/doc/でいつも確認することができる。

テストの自動化

さらに、Clackは品質も重視した。Clack自身に自動化されたテストがあるのはもちろん、テストの実行はJenkins上で管理されている。複数の処理系で同じテストがすべて通ることを必ず確認しているため、処理系依存で動かないようなことはなくなった。また、Clack自身のテストで使っているWebアプリケーションのテストモジュールClack.Testも同時に提供している。

継続的なリリース

そして最後に、何より重要なのは、メンテナンスが継続的にされていることだ。2011年の6月、Clackを公式リリースしたときのことをよく覚えている。バージョンはYY.MM形式で、今後毎月のリリースをする予定だ、とTomohiro Matsuyamaに言った。すると彼は、それ、大変じゃないですか、続かないですよ。僕は、まあ、頑張るよ、とだけ答えた。そして僕は今まで8ヶ月、毎月必ずリリースを続けてきた。そして今後も続ける予定だ。

おわりに

昔どこかで語ったようなことも含まれているけど、こういうことは定期的に言わないと忘れられてしまう。僕が黙っていると、Clackに自信がないから(もしくは未完成だから)だと思われてしまうことに気づいた。もちろん、全くそんなことはない。

過去最も有力だったWeblocksは継続的にメンテナンスされておらず、最新のHunchentoot 1.2でビルドできないためQuicklispでインストールできない。web4rは日本語ドキュメントがあって始めやすいかもしれないが、こちらもメンテナンスされていないため不安が残る (特に拡張性)。Hunchentootは新しいメンテナを得て、バグの多くが修正されたため使ってもいいかもしれない。teepeedee2はよく知らないけど、GitHub上で最もWatchされているCommon Lispプロジェクトだ。ロシアのLisperが作っているRESTASというフレームワークも興味深い。

ただ、僕がCLのWebアプリケーションを作るなら、ClackCavemanが唯一の選択肢だね。

*1:この辺りはQuicklispの登場で多少改善された

*2:同じWebのライブラリとしてわかりやすいからであって他意はない。他のすべてのライブラリにも同じことが言える。Weblocksよりひどいマクロの使い方をしているライブラリを複数知ってる。