какой параметр для нс? - PullRequest
       16

какой параметр для нс?

2 голосов
/ 19 сентября 2010

какой параметр для нс? в документации что-то сказано, но не понятно (по крайней мере мне)


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

1 Ответ

3 голосов
/ 19 сентября 2010

ns является макросом и скрыт, если цитирует имя, чтобы избавить вас от хлопот:

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

другие функции не могут получить аргументы без кавычек, потому что они являются функциями, и функции имеют свои аргументы, которые сначала оцениваются .

макрос ns, как макрос , получает возможность просмотреть и перевернуть свои аргументы до того, как они будут оценены , чтобы он мог получить пространство my-new-name до того, как читатель попытается искать его как имя переменной.

короче говоря, это сохраняет износ и тары на клавиатуре и запястьях;) Шучу, в обоих случаях то, что получает функция, является символом, который они просто различают в том, что вы должны сделать, чтобы передать им этот символ.

для сравнения; если вам куда идти дальше и пропустить (ns 'my-new-namespace) то получится символ 'my-new-namespace цитата и все! вы, вероятно, не хотите, чтобы цитата была частью пространства имен.

если вы хотите, чтобы это было непротиворечивым, вы могли бы написать макросы-обертки, которые принимают символы без кавычек для остальных функций пространства имен, которые просто заключают в кавычки первый аргумент и возвращают вызов реальной функции (помните, что макросы возвращают код для вызова )

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

хотя это нарушит "первое правило макроклуба"

ошибка, связанная с тем, что аргумент является списком, вызвана попыткой использовать (quote my-new-namespace) в качестве имени

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