lambdaと記載できる場所はどこか
よく目にする(lambda ...)
という表記はかなり特殊なものであり、
マクロを抜きにするならば、限定された場所でしか記述できません。
マクロのlambda
とリードマクロの#'
があるため、
式の中で気軽に記載することができるのです。
マクロの例としてはこんな感じ。
(setq *call* (lambda () :hello))
このlambda
マクロは、次のように展開します。
(setq *call* #'(lambda () :hello))
さらにリードマクロ#'
より、次のように展開されます。
(余計なことを言うと、リードマクロの展開タイミングはここじゃないかもしれない)
(setq *call* (function (lambda () :hello)))
最終的にspecial operatorのfunction
の引数に展開されるわけです。
じゃあfunction
の引数のlambda
はマクロ展開されないのか?
されません。
function
の引数はquote
の引数と同じように特殊な場所であり、
評価対象ではないのでマクロ展開されないのです。
ではマクロのlambda
を考えない場合は、lambda
と記載できる場所はどこでしょうか?
答えは下記の通り。
function
の引数- 関数呼び出し時の関数名
function
の引数は上記の例で説明しました。
関数呼び出し時の関数名とは、普通に関数を呼び出すときのリストの第一要素の事です。
((lambda () :hello)) →:HELLO
これだとわかりづらいですよね。
((lambda (a b) (+ a a b b)) 10 20) →60
どうでしょうか。
次の実行とほぼ同じとなります。
(defun testplus (a b) (+ a a b b)) (testplus 10 20) →60
以上で、lambda
の記載できる場所の説明は終わりです。
function
と関数呼び出しの構文の違い
こっちが本題だったりしますが、
special operatorの(function name)
と、関数呼び出しの(name ...)
では、
どちらもsymbol
と(lambda ...)
を記載することができました。
両者は同じものを許容するのでしょうか?
実は違います。
(function name)
が許容するものは下記の通り。
symbol
(lambda ...)
(setf name)
それに対して、(name ...)
が許容するものは次の通り。
symbol
(lambda ...)
つまり関数呼び出しでは、(setf name)
を直接呼び出すことが許されていません。
これはちょっと意外でした。
【参考】http://www.lispworks.com/documentation/HyperSpec/Body/03_abab.htm
If the car of the compound form is not a symbol, then that car must be a lambda expression, in which case the compound form is a lambda form.
つまりは下記のコードは規約違反です。
(defun (setf aaa) (v c) (rplaca c v) v) (let ((c (cons 10 20))) ;; (setf (aaa c) 200) ((setf aaa) 200 c) ;; ★エラー (format t "~A~%" c))
面白いことに、clispではこのコードが全く問題なく動作します。
clispによる実行結果 (200 . 20)
setf
を直接呼び出したいならfuncall
/apply
を使いましょう。
(defun (setf aaa) (v c) (rplaca c v) v) (let ((c (cons 10 20))) ;; (setf (aaa c) 200) (funcall #'(setf aaa) 200 c) ;; ★問題なし (format t "~A~%" c))
実行結果
(200 . 20)
そんな馬鹿なことしてないでsetf
マクロ使えという声が聞こえてきそうですが、
私もそう思います。
なお、当たり前ですが、defsetf
かdefine-setf-expander
で定義されたものの場合は、
関数じゃないのでこの方法では呼び出しできません。