私がCommon Lispを選んだ理由
(blog.djhaskin.com)さようなら、Clojure
- 約7年間Clojureを使ってきたが、CLIアプリの「起動の遅さ」の問題のため、もはや満足できなくなっていた
- babashkaのようなプロジェクトもあったが、GraalVMのnative-imageなどを使っても起動の遅さを解決するのは難しかった
- 「スタンドアロン実行ファイルの高速な起動」が必須要件となり、Clojureはそれを満たせないと判断した
新しいLisp探し
- 新しいLisp言語を探すために複数の言語を調査。これまでのプロジェクトで経験した問題を解決できる言語を模索した
- 「明示的な要件」はなかったが、結果的に次のような基準を整理した
- 「独立して実行可能で高速に起動する実行ファイル」を、妥当なツールチェーンで生成できること(Clojureに対する主な不満の解消)
- Emacsを使えないため、Vimで使えること
- WindowsとMacのサポートが必須であり、Linux/POSIX系OSだけの対応では不十分
- ClojureとJavaのように、他の大規模コミュニティ言語とプラグイン可能であることが望ましい
- ランタイム速度が十分に速いこと(少なくともClojure並み、できればそれ以上)
- マルチスレッド対応が強力で、可能ならGIL(Global Interpreter Lock)のようなものがないこと
- 強力なコミュニティが必須
- 豊かなエコシステムを備え、少なくとも次のライブラリが実装されていること:
- JSONのパースとシリアライズ
- Sqlite3サポート
- HTTPリクエストライブラリ
- Clojureのような関数型データ構造のサポート(ただし、この点の重要度は低め)
- 調査した言語
- Scheme : r6rsとr7rsによる標準化の問題でコミュニティが分裂している状態が魅力的ではなく、エコシステムも小さく要件を満たせなかった
- Racket : 学生時代に使ったことはあるが、ランタイムが遅く重いと感じられ、好みではなかった
- Common Lisp : lisp-lang.orgで見つけた。コミュニティと資料が印象的で、試してみることにした
Magic Happens Here
- Common Lispを学ぶまでの全体的な話は省くが、学習の道のりは険しかった
- 出だしはよくなかった。クリスマスにCLtLv2の本をもらい、それを読んで始めた
- その後HyperSpecを見つけて読み始め、よりよい方向に学習を進められた
- Common Lispには独特の特徴があった
- 標準化された言語であり、JavaというよりCに近い
- 複数のコンパイラ、インタプリタ、ランタイムが標準を実装している
- さまざまな実装をインストールして管理できるRoswellのようなツールがある
- コミュニティで最も人気のある実装はSBCLだと見なされている
- 探索を始めたときにJanetを知っていたらどうだったか?
- Janetには次のような特徴があり、Common Lispを学ぶ前なら満足していた可能性がある
- 簡潔な構文、高速で小さな実行ファイル、C FFIのサポート
- 面白い入門書がある
- 個人的に重視していた要件をすべて満たしている
- それでもCommon Lispを選んだ理由
- 後になって知ったCLOSやCondition Systemのような高度な機能を逃していただろう
- Common Lispはより強力な言語だ
Requirements Met
Common Lispが要件を満たす言語であることを確認したあと、次に使うLispとしてこれを選び、現在まで使い続けている。主な発見は次のとおり。
- 独立実行ファイル:
- Common Lispでは独立実行ファイルを作る方法が複数ある
- 実行ファイルは圧縮の有無によって、起動時間が数秒未満からほぼ即時まで短縮できる
- この機能は付加的なオプションではなく、Lispプログラムを配布する主要な方法として設計されている
- Vimワークフロー:
- 優れた選択肢がいくつもあるが、個人的にはVimのワークフローを自分で構築して使っている
- また、VS CodeもCommon LispのIDEとして使うのに十分良いことがわかった
- Windows/Mac/Linuxサポート:
- SBCLは主要なOSをしっかりサポートしている
- 大規模な命令型エコシステムとの統合:
- ほとんどの実装はC言語との統合をよくサポートしており、CFFIを通じて活用できる
- ランタイム速度:
- SBCLのランタイム速度は非常に速い
- マルチスレッド:
- Common Lisp標準にはマルチスレッドへの明示的なサポートは含まれていないが、主要な実装はこれをサポートしている
- Bordeaux-Threadsというライブラリにより、さまざまな実装間の差異を小さくできる
- lparallel、cl-async、blackbirdのようなライブラリでマルチスレッドや非同期プログラミングが可能
- 強力なコミュニティ:
- コミュニティの活動を見つけ、参加するようになった
- 2024年のコミュニティ調査結果やEuropean Lisp Symposiumを通じて、Common Lispコミュニティの活発さを確認した
- ブログネットワークやsubredditでもコミュニティの支援は強力
- エコシステム:
- ほとんどの人はQuicklispを使っているが、個人的にはOCICLでパッケージを管理している
- Common Lisp Cookbook、CLiki、Awesome CLなどでライブラリや技術情報を探せる
- 特定ライブラリのサポート:
- JSON: jzon
- Sqlite3: cl-sqlite
- HTTPリクエスト: dexador
- 関数型データ構造: FSet, cl-hamt
新しく来た人への参考事項
- Common Lisp Discordで初心者が増えていることもあり、自分がCommon Lispを選び、適応していった過程を共有するために書いた
- この記事がCommon Lispに関心を持つ人の助けになればと思う
2件のコメント
Hacker News のコメント
SBCL を使って、ソースコードがなくても問題を解決した経験が印象的だった。他の技術スタックでは、ソースコードがない状況でこれほど素早く修正することはできなかったと思う
Common Lisp から Clojure に移行した経験を共有し、Clojure の並行性機能が魅力的だった
vim-slime を使って生産性と開発者としての満足度が大きく向上した
Lisp の価値は理解できなかったが、関連する歌は覚えている
Emacs/slime は vim-slime より優れた Lisp IDE だと主張している
Common Lisp を趣味で使っており、SBCL REPL で C# コードを実行したいと考えている
Clojure と babashka を使った CLI アプリケーション開発の経験を共有している
native-image の使用時に問題を経験し、Clojure はほぼ完璧な言語だと考えている
Janet 言語への関心を示し、プロジェクトの GitHub README と FAQ が役立ったと述べている
Lisp を学びたくなった経験を共有しており、特に vim ファンである筆者に惹かれた
Lisp の価値は理解していませんでしたが、関連する歌は覚えています……Lisp の歌はたくさんありますが、YouTube に
Land of Lispという歌があります ;- )