2012-12-07 17 views
7

私はプログラム的にデータログのクエリを構築するが、私は例の機能を説明します問題に実行して維持しようとしています:clojureがバッククォート内の名前に名前空間修飾子を追加するのはなぜですか?

(defn test-expr [attribute] 
    `[?entity ~attribute ?value]]) 

私は(テスト-exprの3)を実行すると、私は出力を期待する:

[?entity 3 ?value] 

しかし、代わりに、私は明らかに私が欲しいものではありません

[mynamespace/?entity 3 mynamespace/?value] 

を取得します。 clojureに "リストを引用して変数を展開してください"と伝える方法はありますか?

+1

理由は、使用しているのと同じ名前の関数や変数を定義することで、ユーザーが誤ってマクロを壊さないようにするためです。 – Cubic

+0

@Cubic、agree。私が理解する限り、これはSchemeの衛生的なマクロとCommon Lispのプレーンなマクロシステムとの間にある種の妥協点です。マクロの定義はCommon Lispのものとほぼ同じです(これはスキームマクロがIMOを書くのが難しいためです)。あるレベルの衛生状態が存在します - シンボルは盲目的に捕捉されませんが、代わりに名前空間の接頭辞が付きます。また、必要に応じて(例えば、擬似的なマクロの場合)通常の置換にいつでも戻すことができます。 –

答えて

9

はい、あります。ここで

(defn test-expr [attribute] 
    `[~'?entity ~attribute ~'?value]) 

あなたは最初の構文の引用をUNQUOTEし、その後すぐに再び記号(~'構造)を引用します。結果は、名前空間のない記号です。

それは、それがどのように動作するかを説明しており、次のように相当します。

(defn test-expr [attribute] 
    `[~(quote ?entity) ~attribute ~(quote ?value)]) 
4

あなたが探しているものそれは、正確な問題あなたのために建設されたブランドン・ブルームhttps://github.com/brandonbloom/backtick

でバッククォートライブラリです説明する。これは、バックスティックのように機能するが、名前空間を持たないコマンド 'template'を提供する。

Clojureでは、準集合と名前空間の解決が1つの機能で混在しています。これはClojureのような言語でマクロを書くのに大きな利点があります.Clojureは "Lisp-1"です(Common Lispとは対照的に、 "Lisp-2"で、関数と変数の名前空間は別です)。

また、これらの機能を統合しないほうが良いかもしれないことに同意しますが、Clojureでのマクロの書き方はそれほどエレガントではないので、なぜそれが動作するのかが分かります。

関連する問題