2012-08-14 3 views
23

私はClojureのマクロについて学んでいますし、コード例は時々構造'~symbolまたは交互~'symbolを持つことになります。 (quote'は、フォームが評価されるのを防ぎ、バッククォートは名前空間の修飾を追加し、〜は引用されたフォームを評価させることを知っています。私の質問は次のとおりです。評価をやめ始めるのはなぜ有用なのですか?私はまた、~'symbol'~symbolが異なると仮定しますが、どうですか?Clojureの〜や〜の目的は何ですか?

答えて

30

~'symbolは、未修飾シンボルを生成するために使用されます。 Clojureのマクロはデフォルトで名前空間を取得するため、マクロ内のシンボルは通常(your-namespace/symbol)に解決されます。引用符で囲まれたシンボルを評価することにより、引用符で囲まれていないイディオムは、単純に非修飾シンボル名-という単純な結果になります。 Clojureの喜びから:

(defmacro awhen [expr & body] 
    `(let [~'it ~expr] ; refer to the expression as "it" inside the body 
    (when ~'it 
     (do [email protected])))) 

(awhen [:a :b :c] (second it)) ; :b 

'~symbolはおそらくマクロまたは類似した何かに名前を挿入するために使用されます。ここでは、symbolは値-let [symbol 'my-symbol]にバインドされます。この値は、symbolを評価してマクロが生成するコードに挿入されます。

+0

:)ありがとう、それは理にかなっています。 – Alex

+0

私には不明なままである点がまだあります:代わりに 'ユーザー/ foo'、の' foo'で '(にunquote(引用ユーザー/ fooという))'結果の名前空間を剥離されることをいつ、どのようにそれが起こるのでしょうか?それは次の形式を評価する 'unquote'の「通常の」振る舞いと一貫していますか? – skuro

+1

最初の例は機能しません。これは '\'でなければなりません( '〜 'it〜expr] ...' – Ming

4

~unquote機能用リーダマクロあります。引用されたリストの中には、シンボルは、その後、むしろ、評価リテラルシンボルとして使用されます

user> (def unquoted 4) 
user>`(this is an ~unquoted list) 
(user/this user/is user/an 4 clojure.core/list) 
user> 

ちょうどこの4のその値に解決された引用符で囲まれていないシンボルとして使用された引用符で囲まれていないシンボルを除くすべてがで最もマクロを書く際によく使われる。 replは、結果リストを出力しているときに名前の前にある名前空間(ユーザー)を表示します。

多くのマクロは、基本的には関数内で行うことができない何かのわずかな変化の束を行うように設計テンプレートです。この考案された例では、テンプレートマクロはdefへの呼び出しを生成することによって関数を定義します。

user> (defmacro def-map-reducer [name mapper reducer] 
     `(defn ~name [& args#] 
       (reduce ~reducer (map ~mapper args#)))) 

#'user/def-map-reducer 
user> (def-map-reducer add-incs inc +) 
#'user/add-incs 
user> (add-incs 1 2 3 4 5) 
20 

比較に:私はしていないよので、私はまた、自動gensyms機能を使用していない第二の例では

user> (defmacro def-map-reducer [name mapper reducer] 
      (let [args-name (gensym)] 
       (list `defn name [`& args-name] 
        (list `reduce reducer (list `map mapper args-name))))) 

#'user/def-map-reducer 
user> (def-map-reducer add-decs dec +) 
#'user/add-decs 
user> (add-decs 1 2 3 4 5) 
10 
user> 

unquotingと構文引用符がはるかに簡単にこれを読んですることができます文言引用

+0

私は以前に引用したリストのシンボルの前に〜を使用したいと思うのは分かっています。私の質問は具体的にはどうして私はお互いに隣り合わせで使うのでしょうか? – Alex

+0

うまくいけば、この例はフィードバックのためのより良い動機を示すでしょう:) –

関連する問題