🔖

Lem Advent Calendar 2023 - Lisp Mode - macroexpand

2023/12/11に公開

これは Lem Advent Calendar の記事です。

Common Lispではマクロを展開するmacroexpand-1をよく使います。

CL-USER> (macroexpand-1 '(loop for i from 1 to 10 collect i))
(BLOCK NIL
  (LET ((I 1))
    (DECLARE (IGNORABLE I)
             (TYPE (AND REAL NUMBER) I))
    (SB-LOOP::WITH-LOOP-LIST-COLLECTION-HEAD (#:LOOP-LIST-HEAD-814 #:LOOP-LIST-TAIL-815)
      (TAGBODY
       SB-LOOP::NEXT-LOOP
        (WHEN (> I '10) (GO SB-LOOP::END-LOOP))
        (SB-LOOP::LOOP-COLLECT-RPLACD (#:LOOP-LIST-HEAD-814 #:LOOP-LIST-TAIL-815) (LIST I))
        (SB-LOOP::LOOP-DESETQ I (1+ I))
        (GO SB-LOOP::NEXT-LOOP)
       SB-LOOP::END-LOOP
        (RETURN-FROM NIL (SB-LOOP::LOOP-COLLECT-ANSWER #:LOOP-LIST-HEAD-814))))))
T

上記のマクロ展開結果を更に展開したい場合は、全ての式を展開するsb-cltl2:macroexpand-all等を使うか、内側の式をコピペして更にmacroexpand-1を呼び出す必要があります。

これをインタラクティブに行うmacrostepと呼ばれる機能がSLIMEには存在し、Lemもこれに対応しています。

LemではC-c Return (M-x lisp-macrostep-expand)コマンドでmacrostepを開始します。

macrostep中のキーバインドは以下の通りです。

Keybind 説明
Tab 次の展開位置に移動
Return カーソル位置のマクロを展開
Backspace Undo
q 終了

おわりに

今日はmacrostepについての紹介でした。
余談ですがudemyにはCommon Lispコースが存在し、MACROSの章のEDITOR TOOL: macrostepという動画があります。
Lemについても紹介されており、参考になるかもしれません。
それではよきmacroexpandライフを

Discussion