【Emacs】
Lispコードを書きながら式を実行する
(slime-eval-last-expression)

  • SLIMEを使うと、Common LispのS式をREPLバッファに移動せずにソースバッファで直接評価できます。
  • C-x C-eで評価結果をミニバッファに表示し、C-u C-x C-eでカーソル位置にコメントとして挿入できます。
  • 結果がファイルに残るため、関数の動作記録がそのままドキュメントになります。
  • C-c C-cでコンパイル、C-M-xでインタプリタ評価と使い分けることで、REPLを開かずに開発サイクルが完結します。

関連記事

1. コードを書きながら式を評価する

Common Lispを書いているとき、式を評価するたびにREPLバッファへ切り替えるのは地味に手間がかかります。

実は、SLIMEを使っていれば、Lispのソースコードを書いているバッファにそのまま結果を表示できます1

キー動作
C-x C-e直前のS式を評価、ミニバッファに表示
C-u C-x C-e直前のS式を評価、バッファにコメントとして挿入
C-c C-c現在のトップレベルフォームをコンパイル

日常的に C-u C-x C-e を使うようになると、LispバッファがREPLとノートパッドを兼ねた場所になります。

1.1. *sccartch*バッファと同じことをしたい

Emacs Lispの場合、 *scratch* バッファで C-j を押すと、計算結果が出力されます2

1.1. *sccartch*バッファと同じことをしたい

これは、eval-print-last-sexpというコマンドで、式と結果がその場にセットで残るので、後から読み返せます。

2. slime-eaval-last-expression(C-x C-u)

SLIMEには、Common Lispの式を評価するコマンドがあります。

2. slime-eaval-last-expression(C-x C-u)

C-x C-e はカーソル直前のS式を評価し、結果をミニバッファに表示します3

2. slime-eaval-last-expression(C-x C-u)
C-x C-e runs the command slime-eval-last-expression (found in
slime-mode-indirect-map), which is an interactive byte-code-function
inslime.elCode language: JavaScript (javascript)

2.1. C-u を付けてカレントバッファに出力

ミニバッファに表示した結果は、すぐ消えてしまいます。
そこで、前置引数 C-u をつけます。

C-u C-x C-e

評価結果がカーソル位置に直接挿入されます4

(+ 1 2 3)
;=> 6Code language: Lisp (lisp)

3. なぜこれが便利なのか

結果がソースファイルに残ることで、「この関数はこういう値を返す」という記録が自然にできあがります。

テストを別ファイルに書くほどでもない小さな確認や、実験的なコードを書いているときに、このスタイルはとくに合います。

コメントとしてファイルに蓄積していけば、後から読んだときに動作の根拠がそのまま見えます。
ドキュメントを別途書かなくても、ファイル自体が実行の記録になります5

3.1. 実際の使い方の流れ

関数を定義して、その場で試す流れはこうなります。

まず関数を書いて C-c C-c でコンパイルします6
これはカーソルが含まれるトップレベルフォームをCommon Lisp側に送ります。

(defun square (x)
  (* x x))Code language: Lisp (lisp)

その下に式を書いて C-u C-x C-e を押します。

(square 5)
;=> 25

(square 12)
;=> 144Code language: Lisp (lisp)

REPLバッファには一度も移動していません。
書いて、コンパイルして、試して、結果がファイルに残ります。

3.2. 定義全体を評価したいとき

C-M-x は、現在のトップレベルフォームを評価します。

C-c C-c と似ていますが、こちらはコンパイルではなくインタプリタとして評価します7
手軽に動作確認したいときに使い分けられます。

  1. SLIMEはSuperior Lisp Interaction Mode for Emacsの略で、Common LispをEmacsから対話的に開発するためのマイナーモードです。2003年にLuke GorrieとHelmut Ellerによってオープンソースプロジェクトとして開発が始まりました。 – SLIME – WikEmacs
  2. *scratch* バッファの C-jeval-print-last-sexp というコマンドで、直前のS式を評価してその場に結果を印字します。SLIMEの C-u C-x C-e はCommon Lispに対して同じ体験を提供します。 – Lisp Eval – GNU Emacs Manual
  3. SLIMEの評価コマンドはEmacs Lispの評価コマンドを模倣して設計されています。C-x C-e はEmacs Lispの eval-last-sexp と対応しており、SLIMEではこれをCommon Lispプロセスに対して実行します。 – Evaluation – SLIME User Manual
  4. 前置引数をつけると結果をバッファに挿入する動作は、C-x C-eC-M-x の両方で使えます。これはSLIMEマニュアルに明記されている仕様です。 – Evaluation – SLIME User Manual
  5. コードと評価結果をひとつのファイルに共存させるこのスタイルは、Common Lispコミュニティで広く実践されているREPL駆動開発と親和性が高いです。The Common Lisp Cookbookでも、コンパイルと評価を組み合わせたインタラクティブな開発フローが推奨されています。 – The Common Lisp Cookbook – Using Emacs as an IDE
  6. C-c C-cslime-compile-defun にバインドされています。コンパイルすると、警告やエラーがエディタ上のソースコードに直接アノテーションされます。評価(C-x C-e)では得られないこの情報がデバッグに役立ちます。 – The Common Lisp Cookbook – Using Emacs as an IDE
  7. C-M-x には defvar を特別扱いする動作があります。通常、defvar は変数がすでに値を持っていれば何もしませんが、C-M-x で評価すると変数を初期値に強制的にリセットします。デバッグ中に変数の状態をリセットしたいときに利用できます。 – Evaluation – SLIME User Manual