T216のquoteについて
時の人tazantさんのブログ「Lispのひび」にて最近書かれているquoteについて、
いくつが疑問が溜まってきたのでまとめて書き散らしています。
***全ての始まり***
独自の仕様については、バッククォートもクォートも同じクォートして扱う。
バッククォートはクォートの進化系だから。
リストを作るときも「’」を使い、consの代わりにも、appendの代わりにもなる。
(2008-09-20 マクロ)
「クォートとバッククォートの同一視」をして大丈夫なのかが最大の論点。
私はこれに対しては懐疑的。
CL等の
(defmacro my-search (key) `(assoc ',key *a-list*))
や
(defmacro abbrev (shot long) `(defmacro ,short (&rest args) `(,',longlame ,@args)))
はどうやって表現するのか気になります。
(2つ目のプログラム片はOn Lisp 16.1節「省略」より)。
***’,foo or ‘(,foo)***
,x = (comma x)です。'(comma foo) = ‘(,foo)となるようになっています。
これはある程度独自な仕様ですから、そこら辺はご了承ください。
***中略***
‘(comma foo)と’,fooの区別は付きませんね。
(2008-09-20 マクロの世界へ)
[疑問1]
‘(comma foo) は結局 ‘(,foo) なのか ‘,foo なのかどっち?
私としては ‘(,foo) に展開されると少々やりにくい気がしますが…
***quoteはcommaが無くても特別?***
基本的に評価基準は一致しています。重大なことに気が付きました。
quoteは「,」をつけない限り、そのままです。次の例でどうでしょうか。
***中略***
よって、'(‘bar baz)というリストを作りたいなら、こうなります。'('quote (('quote bar) baz)) ;=> (quote ((quote quote) (((quote quote) bar) baz))) ;=> (quote (quote (((quote quote) bar) baz))) ;=> (quote (quote ((quote bar) baz))) ;=> (quote ((quote bar) baz)) => '('bar baz)
shiro 2008/09/21 03:27 ふーむ。クオートされた式中において、
1. (quote quote) は quote に置換
2. (quote comma) は comma に置換
3. (comma expr) は exprを評価して置き換え
4. 置換の結果生成されたquote, commaはその効力を失う
とすれば良いのかな。
(上同記事コメント欄)
[疑問2]
『quoteは「,」をつけない限り、そのまま』とのことですが、
実際には(quote quote) の動作が特別扱いされるんですよね。
(quote ((quote quote) a)) を評価すると (quote a)でしょうか?
***,@的な動作の例が見たい***
commaの仕様は、
* ,@みたいなもの。アトムならそのまま付け加える。
* リストなら外の()を外す。もし付けたいなら,(…)でいい
(2008-09-21 マクロの仕様)
[疑問3]
「もし付けたいなら,(…)でいい」とはどういうことでしょうか。
,(func arg)は関数呼び出しとなってしまうため、
括弧を付けたい、取りたいとは別問題になってしまう気がします。
[疑問4]
古い記事に戻りますが、
(= filter (macro (func arg) '(,func ,arg))) => (macro (func arg) '(,func ,arg)) (filter reverse '(1 2 3)) ; 内部での状態=> (quote ((comma func) (comma arg))) ; quote評価後=> (reverse '(1 2 3)) ; もう一度、マクロの最後を評価=> (3 2 1) => (3 2 1)
commaがCLの,@のようにリストの外の()を消してしまうなら、
(quote ((comma func) (comma arg)))
は
(reverse 1 2 3)
となってしまうのではないでしょうか。
***マクロ引数の展開***
fujita-y 2008/09/21 12:14
もしかして、(= func (lambda (x) (+ x x)) (= hoge (macro (x) '(x ,(x 1)))) (hoge func) => (quote (func ,(func 1))) => (quote (func 2)) => (func 2)ってことなのかな?
tazant 2008/09/21 13:16
マクロ引数(x)は展開時には評価されずに、
マクロとして再評価すると呼び出し元+引数の環境下で
普通の他の関数などの変数として評価されます。
(2008-09-21 マクロに挑戦! コメント欄)
[疑問5]
マクロ引数xが展開時にコンテキストに関わらず展開されないのであれば、
‘(x ,(x 1))
の最初のxはxというシンボルがそのまま残り、
,(x 1)
は展開時に『xという関数に1を付けて呼び出したもの』の値に置換されると思います。
つまり、
(x 未定義値)
というリストが出来上がるのではないかと。
これがfujita-yさんが仰るように
(quote (func ,(func 1)))
に変形されるのであれば、これは展開時にxが展開されるということではないのでしょうか?