【Common Lisp】
SBCLの素のREPLは使いにくい
(readline)

関連記事

1. なぜ矢印キーが効かないのか

SBCLを使っていたら、矢印キーを押すと ^[[D のような記号が画面に現れ、カーソルを左に動かして入力を修正することもできません。
上下の矢印キーで過去の式の履歴を呼び出すこともできません。

これはバグではなく、SBCLの設計によるものです1

1.1. readlineライブラリ

ターミナルで矢印キーの履歴呼び出しやカーソル移動ができるのは、readline というライブラリが担っている機能です。

たとえば、bashやzshはreadlineを組み込んでいるため、自然にそれらの操作ができます。
しかし、SBCLはreadlineを組み込んでいません。

理由のひとつはライセンスで、readlineはGPLで配布されており、SBCLのライセンス構成と噛み合わない2
矢印キーを押すと、ターミナルが送ってくるエスケープシーケンスがそのまま文字として入力されるため、あの見慣れない記号が現れます。

2. そもそも直接使う想定ではない?

Common Lispの開発スタイルは、EmacsとSLIMEまたはSLYを組み合わせるのが主流です3

SLIMEはEmacsからSBCLのプロセスに接続し、エディタ側でライン編集・補完・デバッグを一手に引き受けます。
この環境ではターミナルのREPLを直接操作することがそもそもありません。

これもSBCLの開発者にとってターミナルREPLの使い勝手の優先度が低い原因なのかもしれません。
SBCLは、動作確認のために式をひとつ評価する用途には使えますが、それ以上の開発作業の場としてはやや不便です。

「REPLがあるからターミナルから使えるだろう」と思って起動したのですが、素直にEmacs上で動かした方がよさそうです。

3. とりあえず使いたい場合はrlwrap

ターミナルでSBCLのREPLを使うときには、rlwrapを経由して起動することもできます。

rlwrapはreadlineを外側から被せるラッパーで、これを挟むだけで矢印キーによる履歴呼び出しとカーソル移動が動くようになります4

rlwrap sbclCode language: Bash (bash)

毎回入力するのが面倒であれば、シェルのエイリアスに登録しておきます。

alias sbcl='rlwrap sbcl'Code language: Bash (bash)

rlwrapはmacOSならHomebrewで、Linuxならaptやpacmanで入手できます。

  1. SBCLはパブリックドメインとMIT・BSD系ライセンスの混合で配布されています。 – History and Copyright – Steel Bank Common Lisp
  2. フリーソフトウェアライブラリは通常LGPLで配布されることが多く、readlineがGPLを採用しているのは珍しい例です。readlineにGPLを採用したCLISPという別のCommon Lisp実装は、ライセンス上の制約を受けることになりました。 – GNU Readline – Wikipedia
  3. SLIMEはSuperior Lisp Interaction Mode for Emacsの略で、2003年にEric MarsdenのSLIMを起源とします。100名以上のLisp開発者がコードを提供してきました。SLYはSLIMEの後継フォークで、2014年に分岐し、より豊富な機能と改善されたUIを目指しています。 – SLIME: The Superior Lisp Interaction Mode for Emacs / GitHub – joaotavora/sly
  4. rlwrapは1999年にHans Lubが作成したツールで、GNU Readlineライブラリを内部で使用しています。セッションをまたいだ入力履歴の保存や、Ctrl+Rによる履歴検索など、bashと同等の操作が使えるようになります。 – GitHub – hanslub42/rlwrap