八発白中

技術ブログ、改め雑記

Day 8: Shelly

これは fukamachi products advent calendar 2016 の8日目の記事です。

今日はShellyについて話します。

注意

今まで取り上げたツールとShellyの異なる点は、Shellyは古いプロジェクトであり現在非推奨である点です。これを読んで技術的な興味以上の実用的な意図で使うことは推奨しません。

シェルとS式

Common Lispのアプリケーションはターミナルからスクリプトとして実行することはあまり考えられていません。普段はREPLでS式を入力して実行するだけで十分です。けれどもSSHで入ったサーバでアプリケーションを実行したい場合には面倒なことになります。

sbcl --eval '(ql:quickload :clack)' --eval '(clack:clackup #P"app.lisp" :server :fcgi :port 3000)'

いわゆるワンライナーですが、単にライブラリをロードして関数一つ呼ぶだけにしては大袈裟です。

きっかけは些細なことから

Clackの影響元となったPerlPlackにはplackupというWebアプリケーション実行用のコマンドがあります。

plackup app.psgi
plackup --server HTTP::Server::Simple --port 9090 --host 127.0.0.1 app.psgi

このコマンドを見ていて気づくことがありました。--serverというのはclackup:serverに相当します。このコマンドを受け取ってキーワード引数に変換して関数呼び出しすれば汎用的なコマンドラインインターフェースが作れるのではないか。

その突発的なアイデアで作られたのがShellyです。

Shellyを使うと先ほどのclackupのコマンドがこのように実行できます。

shly -Lclack clackup app.lisp --server :fcgi 3000

シェルから渡された引数はすべて文字列になるのですが、値によって適切な型に変換してから関数に渡します。同名のファイルがあるときはpathnameに、コロンで始まるときはキーワードに、数値のときは数値に暗黙に変換されます。

初期はPerl5で書かれていました。Common Lispでない理由は処理系の依存をなくすためにブートストラップが必要なためです。

CIMやRoswellへの影響

コマンドラインCommon Lispアプリケーションを実行したいという要求は思ったよりもあったようですが、Shellyのインターフェイスが最善かというと疑問もありました。僕自身Shellyは実験的なプロジェクトだと捉えており、多く使ってもらうことで改善点が見つかればと考えていました。

それから2年が経とうという頃、κeenさんがCIM (Common Lisp Implementation Manager)を作りました。処理系の管理ツールなのですがコマンドラインインターフェースを備えており、それがShellyに影響をされているそうです。

さらに1年後、snmstsさんがCIMに影響を受けてRoswellを作りました。CIMと同様に処理系の管理ツールですが、こちらは移植性のためにCで書かれています。コマンドラインインターフェイスの抽象度はShellyやCIMに比べて低いですが、RoswellスクリプトによるCommon Lispスクリプト化が簡単になりました。

そしてその数ヶ月後、takagiさんがLakeを作りました *1。これはGNU makeのCommon Lisp版と言えるものであり、Shellyのshlyfile *2に相当する仕組みです。直接的なShellyの影響はありませんが、Shellyが使われなくなりRoswellスクリプトが一般的になったという環境の変化から自然と生まれたものでしょう。

そういう過程を経てShellyはもうすべての機能を他のプロジェクトに譲りました。Shellyのプロジェクトは廃れましたが、コマンドでの実行環境としての実験は後のプロジェクトに少しばかり影響を与えたという点で成功だったと言えるかもしれません。

おわりに

ShellyはGitHubで公開されていますが現在は非推奨です。

明日のアドベントカレンダーは9日目のQuickdocsについてです。お楽しみに。

*1:元はRudolph-Millerリポジトリだったがtakagiさんがジャックして勝手に開発した

*2:shlyfile.lispに関数を定義することで自由にプロジェクトローカルのコマンドを作れる機能