私は Let Over Lambda を読んでいます。これは、かなり深く階層化されたマクロ オーサリングを扱っています。それは魅力的で、私はほとんどそれについていくことができています.
第 4 章では、Hoyte が CL-PPCRE の一致および置換関数用のリーダー マクロを実装しており、次のようなことができます。
(#~m/(foo|bar)\d+/ "Some foo99") ; matches!
(#~s/foo(\d+)/bar\1/, "Some foo99") ; "Some bar99
これを実現するために、二重バッククォートを使用するマクロを定義します。実際には、引用符で囲まれた値を必要とするラッパー マクロによって展開されるためです (ラムダ形式を返します)。準引用リスト内で、次のシーケンスが使用されていますが,',varname
、これについては理解できません。ここでイニシャルは何をし,'
ますか?
(defmacro! pcre/match-lambda-form (o!args)
"Expands to a lambda that applies CL-PPCRE:SCAN"
``(lambda (,',g!str)
(cl-ppcre:scan ,(car ,g!args)
,',g!str)))
defmacro
実際には、本を読んでいない場合にわかりやすくするために、単に を使用するものにそれを抽出した方がよいでしょう。str
はシンボルでargs
あり、リストです:
(defmacro pcre/match-lambda-form (args)
"Expands to a lambda that applies CL-PPCRE:SCAN"
``(lambda (,',str)
(cl-ppcre:scan ,(car ,args)
,',str)))
引用符は基本的に内側の部分を二重引用符で囲んでいるので、結果を 2 回引用符で外すことができますか? 'str
単にstr
?ではなく、展開された形式に効果的に入れる。
編集 | Terje D.とREPLで遊んでいる人たちのおかげで、これはほとんど状況です:
(defvar a 42)
(equal ``(,,a) '(list 42)) ; T
(equal ``(,a) '(list a)) ; T
(equal ``(,',a) ''(42)) ; T
(equal ``(a) ''(a)) ; T (obviously)
そう:
- 二重引用符なし、フォームは完全に展開されています。
- 単独引用符なし、フォームは展開されません。
- コンマで引用されていない場合、フォームは完全に展開され、結果が引用されます。