2012-11-06 29 views
0

比方說,我想定義一個宏名爲defsomething這樣的:Clojure的宏:得到語法報價/名稱空間限定的符號

(defspecial a x) 

...擴展成這樣:

(def a (f `a x)) 

那語法引用`a有棘手的部分。我沒有看到如何正確地將當前名稱空間附加到該符號,以便它的行爲像語法引用。例如:

(defmacro defspecial [var-symbol expr] 
    `(def ~var-symbol (f '~var-symbol ~expr))) 

(defspecial a x) 

...擴展爲:

(def a (f 'a x)) 

...這是接近,但第二a不是合格的命名空間。

我知道我能使用*ns*

(defmacro defspecial [var-symbol expr] 
    `(def ~var-symbol (f (symbol (name (ns-name *ns*)) (name '~var-symbol)) ~expr))) 

...但我不喜歡這樣;它不僅是醜陋,*ns*是rebindable,所以這將是可能的:

(binding [*ns* (the-ns 'clojure.core)] 
    (defspecial a 5)) 

不幸的是,Clojure中顯然沒有syntax-quote形式`像它quote'。那麼,我應該如何最好地實現這個宏呢?

+0

\'不會追加當前名稱空間。如果你沒有給出你想要的和爲什麼不起作用的例子,你很難理解你想要達到的目標(我的意思是,我想知道你想在某處放置語法引號,我在說關於你的宏實際應該做什麼)。 – Cubic

+0

背景是這是一個將函數組合在一起以創建解析器的庫。一個更高級別的函數(稱爲'lbl')接受一個函數(稱爲「p」)並將其包裝到另一個函數中,該函數爲「p」返回的任何內容添加一種「標籤」(對於解析函數的語法錯誤處理)。我想定義一個用於定義解析器函數的'def'版本,並且我希望它能夠自動調用函數中的'lbl',並用它們的變量名稱來標記它們。命名空間資格在這裏會很好,因爲我預計會有很多標籤碰撞。 – user644104

回答

1

你真的嘗試過最後一個例子嗎? *ns*的編譯器綁定發生在編譯時,就像宏展開一樣,所以你所做的運行時綁定應該對defspecial的行爲沒有影響。

+0

唉!你是對的。我應該事先做過測試。看起來這是答案,雖然它對我的口味仍然有點難看,感嘆。但非常感謝你! – user644104