defsubst で定義された関数は、 byte compile の際にインライン展開される。 しかし、どういう場合にインライン展開されるのだろう? 早速実験してみよう。
まず、defun で定義された関数が、 byte compile の際にインライン展開されない例を見ておこう。 以下の例では、foo を byte compile しても、 plus2 という関数名が残るので、 plus2 が foo へインライン展開されていないのが分る。
(defun plus2 (x) (+ x 2)) (byte-compile 'plus2) → #[(x) "^H\301\\\207" [x 2] 2] (defun foo (lst) (plus2 lst)) (byte-compile 'foo) → #[(lst) "\301^H!\207" [lst plus2] 2]
次に defsubst がインライン展開されるのを実際に見るために、 plus2 を defsubst で定義して、 foo を byte compile してみる。 plus2 という関数名は消えて、インライン展開されているのか理解できるだろ。
(defsubst plus2 (x) (+ x 2)) (byte-compile 'plus2) → #[(x) "^H\301\\\207" [x 2] 2] (defun foo (lst) (plus2 lst)) (byte-compile 'foo) → #[(lst) "^H\211^Y\302\\)\207" [lst x 2] 3]
plus2 を funcall で呼び出す場合はどうだろう? これも以下のようにインライン展開される。
(defun bar (lst) (funcall 'plus2 lst)) (byte-compile 'bar) → #[(lst) "^H\211^Y\302\\)\207" [lst x 2] 3]
では、mapcar の第一引数に与えてみるとどうだろう? 明らかに plus2 は関数だと分るはずだが、 以下のようにインライン展開されないようだ。 "'" を "#'" に変更し、関数だと明示しても結果は変らない。
(defun baz (lst) (mapcar 'plus2 lst)) (byte-compile 'baz) → #[(lst) "\301\302^H\"\207" [lst mapcar plus2] 3]
どうやら defsubst で定義された関数は、 単純に関数として呼び出される場合と、 funcall で呼び出される場合にインライン展開されるようである。