KDOC 700: defsubstで定義した関数はバイトコンパイルで呼び出し元に展開される

この文書のステータス

  • 作成
    • 2026-10-18 貴島
  • レビュー
    • 2026-10-18 貴島

概要

Emacs Lispで defun の代わりに defsubst で関数を定義すると、その関数を呼ぶコードをバイトコンパイルしたときに、関数の中身が呼び出し元に埋め込まれる。関数呼び出しの手間がなくなる。

etc=$(emacs -Q --batch --eval '(princ data-directory)')
info -f "$etc/../../../info/elisp.info.gz" -n 'Inline Functions' -o - | sed -n '6,9p;20,22p'
An “inline function” is a function that works just like an ordinary
function, except for one thing: when you byte-compile a call to the
function (*note Byte Compilation::), the function's definition is
expanded into the caller.
But it also has disadvantages.  For one thing, it reduces flexibility;
if you change the definition of the function, calls already inlined
still use the old definition until you recompile them.

埋め込まれたことは、呼び出し元をバイトコンパイルしたあとで関数を定義し直すと分かる。 (* x 2) を (* x 3) に定義し直してから1を渡すと、 defun 版は新しい定義を使って3を返す。 defsubst 版は埋め込まれた古い中身のまま2を返す。

(defun kd-mul (x) (* x 2))
(defsubst kd-mul-inline (x) (* x 2))
(let ((f (byte-compile (lambda () (kd-mul 1))))
      (g (byte-compile (lambda () (kd-mul-inline 1)))))
  (defun kd-mul (x) (* x 3))
  (defsubst kd-mul-inline (x) (* x 3))
  (format "defun版: %d、defsubst版: %d" (funcall f) (funcall g)))
defun版: 3、defsubst版: 2

関連

なし。

Backlinks