Common Lispとリアル・ワールドを繋ぐ「Roswell」の紹介
「Roswell」というプロダクトがある。
clfreaksのPodcastで聴いたことがあるかもしれないし、数週間前にLisp Meet Upで佐野さん (@snmsts) の発表を聞いたかもしれない。
知名度の割には意外と長く開発が続いているプロダクトだ。プロジェクトの最初のコミットが2014年7月30日なので、もう11ヶ月ほど開発が継続していることになる。開発は未だ活発で、バグ報告をするとその日のうちに修正がmasterに入ることが多い。
僕が働いてるサムライト株式会社では、個人の開発マシンではもちろん、アプリケーションサーバでも日常的に使われている。
RoswellにはChefのrecipeも既にある。
先日RoswellはTravis CIとCircle CI用のインストーラスクリプトも提供し始めた。これにより、CIサービスでRoswellを使ってCommon Lispプロダクトを継続テストできるようになった。
さらに、Common Lispのいくつかのプロダクト――Clack、Qlot、Woo――はRoswellユーザ向けに便利なスクリプトを提供している。
このようにRoswellの適用範囲は増えていく一方だ。
人々の声
Common Lispが何故愛されないのかはよくわからないけれど今の僕にはroswell無しでCLを使う気が起きない程度に素のCLとコマンドラインとの間に面倒さを感じる余地があったということに気がついている。こういうことの積み重ねだと信じたい。
— Masatoshi SANO (@snmsts) 2015, 5月 13
NO ROSWELL, NO LIFE.
— Rudolph Miller (@Rudolph_Miller) May 13, 2015
これくらいの気持ちでいこう。 https://t.co/3qY7aDSfZX
— Masatoshi SANO (@snmsts) 2015, 5月 13
no roswell, no life
— Masayuki Takagi (@kamonama) 2015, 5月 31
Roswellはじわじわと現実世界に染み込んでおり、もはやこれなしで開発することは苦痛でしかないと感じる。
しかし、この温度感はclfreaksのメンバー以外にはまったく伝わってないと思う。それは佐野さんの控えめなマーケティング戦略のせいかもしれないが *1、それだけでなく、Roswellがあまりに急速に我々の間に広まって当たり前になってしまったために、あえて今更言及するほどでもない存在になってしまったからでもある。
この記事では改めてRoswellというプロダクトの紹介をする。
Roswellのインストール
Mac OS XならHomebrewで簡単にインストールできる。
$ brew tap snmsts/roswell $ brew install roswell
その他のOSはREADMEを参照。
Roswellをインストールするとバイナリ版SBCLとQuicklispがインストールされる。
Common LispのインストーラとしてのRoswell
RoswellはCommon Lisp処理系のインストーラとして開発が始まった。RubyのRVMやrbenv、PerlのPerlbrewなどを想像するとわかりやすい。
$ ros install sbcl $ ros install sbcl/1.1.8 # バージョン指定 $ ros install ccl-bin # Clozure CL
CIMと違ってSBCLとClozure CLにしか対応していないが、手広くない分この二つの処理系では問題なく動くことが期待できる。
インストールされた処理系、バージョンは切替ができ、ros
で起動されるCommon Lispを変更できる。
$ ros run -- --version SBCL 1.2.12 $ ros use sbcl/1.1.8 $ ros run -- --version SBCL 1.1.8
$ ros run * (+ 1 2) 3 * (lisp-implementation-type) "SBCL" * (lisp-implementation-version) "1.1.8"
インストールされているLispはros list installed
で確認できる。
$ ros list installed detail shown by ros list installed [implemntation] implementations: ccl-bin sbcl-bin sbcl/1.1.8 sbcl
RoswellがCommon Lispとシェルを繋ぐ
Common Lispのインストーラというだけなら環境構築を楽にしてくれるツールというだけで話は終わる。
しかし、Roswellは意図せず二弾式ロケットのようになった。その二弾目の機能が「シェルとの連携」だ。
今までCommon Lispでポータブルなスクリプトを書くのは難しかった。処理系によってコマンドライン引数が異なるからだ。
$ sbcl --load script.lisp --eval '(sb-ext:exit)' $ ccl --load script.lisp --eval '(quit)' $ clisp script.lisp
これに対しRoswellではros
というコマンドでラップされており、どの処理系も同じように扱える。
$ ros -l script.lisp
Roswell Script
これだけではない。.lisp
のようなファイルではなく、シェルコマンドとしてCLであることを意識せずに使えるスクリプトも書くことができる。
ros init [スクリプト名]
を実行するとスクリプトのひな形が生成される。
$ ros init hoge Successfully generated: hoge.ros
この中身はこのようになっている *2。
$ cat hoge.ros #!/bin/sh #|-*- mode:lisp -*-|# #| exec ros -Q -- $0 "$@" |# (defun main (&rest argv) (declare (ignorable argv)))
この「.ros」という拡張子のついたスクリプトは「Roswell Script」と呼ばれており、既にいくつかのプロダクトで使われている。
Clackはサーバ起動スクリプトとして「clackup」を、Qlot *3 はラッパースクリプト「qlot」を、Wooは自身の実行可能ファイルインストーラ「install-woo」を提供している。
これにより、Common Lispスクリプトを配布するときの手間がかなり省けることになる。単にRoswellをインストールしてください、で説明は終わる。
このRoswellの副次的な機能はShellyを殺しつつある。僕はこの変化を歓迎している。サムライトではShellyを使っていないし、今後移行する予定もない。Roswellを使おう。
まとめ
Roswellはインフラだ。今まで不可能だったことを可能にするようなプロダクトではないが、我々の生活をより良いものにしてくれる。いずれは入門書のセットアップに必ず出てきて「常識」と呼ばれるようになるだろう。
*1:Roswellの現在のバージョン番号は0.0.2.33。いつになったらバージョン1.0を迎えるのか。
*2:shebang行が #!/bin/sh だが、exec rosによりrosコマンドに入れ替わる。このハックの詳細は「割と処理系ポータブルなCommon Lisp実行可能ファイルを作る」で解説されている。
*3:プロジェクトローカルにQuicklispをインストールするツール。https://github.com/fukamachi/qlot