2013-07-02 24 views
18

私はかなり深く階層化されたマクロオーサリングを扱うLet Over Lambdaを読んでいます。それは魅力的で、私はほとんどそれに追いついて管理しています。第4章でCommon Lispダブルバッククォート、クォート解除、クォート、アンクォートシーケンス?

はホイトは、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))) 

は、基本的に内部部品をダブル引用符引用符はありますか?効果的にstrの代わりに'strを展開したフォームに入れますか?

EDIT |テリエ・D.とREPLで遊んでいくつかのおかげで、これはかなり状況です:

(defvar a 42) 

(equal ``(,,a) '(list 42)) ; T 
(equal ``(,a) '(list a)) ; T 
(equal ``(,',a) ''(42))  ; T 
(equal ``(a) ''(a))  ; T (obviously) 

だから:

  • 二重引用符で囲まれていない、フォームが完全に展開されます。
  • 単独引用符で囲まれていない形式は展開されません。
  • コンマで引用符で囲まれていないと、フォームが完全に展開され、結果が引用されます。
+0

あなたの最後のdefmacro参照 'str':

はどのように参照してください。それは何ですか?それはどこに定義されていますか? 'pcre/match-lambda-form'がどのように呼び出されているかを見せてもらえますか? –

+0

ああ、現実にはマクロのレイヤーがたくさんあるので、これはいくつか説明するつもりです。この本は、マクロオーサリング(楽しい、そして教育のため)の境界を押し進めています。'str'は、囲む' LET'で定義されたシンボルで、安全に使用できる変数名を表します。 – d11wtq

+0

'pcre/match-lambda-form'は、' 'pcoo/match-lambda-form '(" foo "))'のように呼び出されます。 '#〜m/foo /'の形式になります。 – d11wtq

答えて

11

二重逆引用形式の評価では、内側の逆引用符が最初に処理され、結果は一重引用符付きの形式になります。内部のバッククォート形式の評価中、2つのコンマで始まる要素のみが評価されます。しかし、これらの二重引用符で囲まれていない要素を評価した結果は依然として(単独で)引用されておらず、結果として単一引用符付きの形式が評価されたときに再度評価されます。内部のバッククォート形式でのみ評価を行うには、通常の見積もりを挿入しなければならず、結果として,',となります。

(let ((tmp (gensym))) 
    ``(lambda (,tmp ,,tmp ,',tmp)())) 

`(LAMBDA (,TMP ,#:G42 #:G42) nil) 
+1

うわー、それは少し複雑です。私はちょうどいくつかの基本的な二重バッククォートと、それぞれの場合に何が起こるかを見るために、今引用していないバリエーションを試しています。私は今それを得る、ありがとう:) – d11wtq

+2

@ d11wtqあなたはhttp://www.cs.cmu.edu/Groups/AI/で利用可能な 'Common Lisp the Language'の付録C(バッククォート)を見たいかもしれません。 html/cltl/clm/node1.htmlには、サンプル実装とバッククォート構文の例が含まれています。 –

1

ザに評価方法を参照、 '、Xトリックは別の評価からXを保護するために使用されます。

 (setq a 'fn) 
    (let ((x 'a)) ``(,,x ,',x)) ==> `(,a a) ==> (fn a) 

    ;; ``,',X ==> `,(quote "the value of X") ==> "the value of X" 

    ;; ``,,X ==> `,"the value of X" ==> "the value of the value of X" 
関連する問題