2010-09-19 97 views
2

ns是什麼參數?文件說了什麼,但目前還不清楚(對我來說,至少)ns是什麼參數?


my-new-namespace=> (doc ns) 
------------------------- 
clojure.core/ns 
([name docstring? attr-map? references*]) 
Macro 
    Sets *ns* to the namespace named by name (unevaluated), creating it 
    if needed. 

...the rest of the documentation was not copied 

的混亂來自所有以命名空間發揮其他功能:


user=> (find-ns 'my-new-namespace) 
nil 
user=> (remove-ns 'my-new-namespace) 
nil 
user=> (create-ns 'my-new-namespace) 
#<Namespace my-new-namespace> 
user=> (ns 'my-new-namespace) 
java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol (NO_SOURCE_FILE:26) 
user=> (ns my-new-namespace) 
nil 
my-new-namespace=> 

find-ns, create-ns, remove-ns採取my-new-namespace報價,而ns需要my-new-namespace未上市

那麼,這是怎麼回事?爲什麼有些人會得到一個引用表格,其他人得到和不加引號表格my-new-namespace

什麼是在每種情況下,my-new-namespace

PS:想我找到了這個問題的答案,因爲我在這裏寫的問題,但它似乎和有趣的練習,所以這個問題仍然有貼:d

回答

3

ns是一個宏觀和引擎蓋,如果下引用名稱,以節省您的麻煩:

user> (macroexpand '(ns foo)) 
    (do (clojure.core/in-ns (quote foo)) (clojure.core/with-loading-context 
     (clojure.core/refer (quote clojure.core)))) 

其他功能不能逃脫不帶引號的參數,因爲它們是功能,和功能有有爭論評估第一

的NS宏,作爲宏觀,得到來看待和玩弄它的參數他們正在評估之前,所以它可以在我的新的命名空間之前把讀者試圖尋找它作爲一個變量名稱。

簡而言之,這可以節省您的鍵盤和手腕上的磨損和皮重;)開玩笑,在這兩種情況下,功能所接收的是一個符號,它們只是不同之處在於您必須做的將符號傳遞給它們。

for comparason;如果你在哪裏繼續並通過(ns 'my-new-namespace)它會得到符號'my-new-namespace報價和所有!你可能不希望報價成爲名稱空間的一部分。

如果你想使它保持一致,你可以編寫一個包裝宏,爲其餘的命名空間函數帶上未加引號的符號,這些函數只需引用第一個參數並返回對實際函數的調用(請記住,宏返回的代碼是所謂的)

(defmacro my-find-ns [name] 
    `(find-ns (quote ~name))) 

儘管這會打破「宏觀俱樂部的第一條規則」

有關參數錯誤時正在一個列表是通過它試圖使用(quote my-new-namespace)作爲名字

引起
+0

感謝您向我的知識數據庫中引入新表單(macroexpand):) – Belun 2010-09-19 20:29:07

+0

我通常使用macroexpand-1(不太詳細)。它有助於解釋錯誤信息的陌生性 – 2010-09-20 17:28:49