Day 4: cl-project
これは fukamachi products advent calendar 2016 の4日目の記事です。
今日はcl-projectについて話します。
コーディングスタイルの提唱
前回の記事のCavemanからは話が前後します。
Clackの思想は疎結合性と再利用性を高めることでした。それはClackを使ったアプリケーションだけでなくClack自身についても同様であり、つまりは一般的なCommon Lispアプリケーション自体の疎結合性を高めることも目指したものでした。
Common Lispにはアプリケーションの分割単位として「パッケージ」と「システム」があります。「システム」はプロジェクトの一つの読み込み単位であり、複数のファイルと複数のパッケージを含みます。
他のプログラム言語に親しんだ人には違和感があるかもしれませんが、Common Lispのパッケージはファイル単位と結びついていません。つまり、1ファイルに複数のパッケージを書くことができますし、1つのパッケージを複数のファイルで共有することもできます。
従来のCommon Lispアプリケーションで一般的だったのは、package.lisp
というファイルにdefpackage
(パッケージ定義文) をまとめてしまい、それぞれのファイルでは一つのパッケージを共有するものでした。
このスタイルにはいくつもの問題があります。
- ファイルに分割されていてもシンボルの衝突が起こる
- 依存ライブラリが実際にどのファイルで使われているかわかりづらい
defpackage
宣言が同一ファイルにないため管理がおざなりになりがち
特に依存ライブラリやファイルの依存関係がわかりづらくなることが大きな問題です。
そこでClackでは1ファイルにつき1パッケージのスタイルを提唱しました。そして:use
の使用を極力やめ、必要なシンボルを:import-from
で列挙することにより依存しているシンボルを一覧できるようにしました。これらはAriel LabsのCL Style Guideで詳しく書いています。
提唱から布教へ
その頃僕はいくつものCommon Lispライブラリを並列で作り始めていました。Common Lispライブラリを作り始めるときに.asd
ファイルを作ったりREADMEを置いたりテストファイルを配置したりなど、何度も同じことをしなければなりません。
そこでこれをテンプレート化してライブラリの雛形を生成できるライブラリを作りました。それが「cl-project」です。
生成される雛形のプロジェクトは当然ながら僕が推奨するスタイル、Clackスタイルのプロジェクト構成でした。ファイル毎にパッケージが定義され、READMEがあり、テスト用のファイルも同時に生成されます。
競合としてQuicklispのZackが作ったquickproject というものもあります。こちらを愛用している方もいると思いますが、違いとしては1パッケージ1ファイルのスタイルではないことと、テストの雛形は生成されないことです。
この地味な名前のプロダクトは実は僕のプロダクトの中ではかなりよく使われている部類です。
普及のためという戦略的な意図はなかったにせよ、結果的にClackスタイルの布教にも貢献をしました。現在では新しいプロダクトの多くは1パッケージ1ファイルのスタイルで書かれ、Proveが使われたプロジェクトも多いです。
おわりに
cl-projectはGitHubで公開されており、現在Starは69です。
明日のアドベントカレンダーは5日目のningleです。お楽しみに。