为什么我不能使用Clojure声明命名空间和方法

Mar*_*hko 4 namespaces clojure

我尝试在clojure中编写一个宏来设置命名空间并自动添加一些方法.我的宏没有工作,我将其跟踪到一个do语句.在do中声明一个新的命名空间是不可能的,然后立即在该命名空间中声明一个方法.为什么?

这不起作用:

(ns xyz)
(do
  (ns abc)
  (prn *ns*)
  (defn tst[] (prn "test" *ns*)))

(prn "after" *ns*)
(tst)
Run Code Online (Sandbox Code Playgroud)

这工作(do之前的名称空间声明):

(ns xyz)
(ns abc)
(do
  (prn *ns*)
  (defn tst[] (prn "test" *ns*)))

(prn "after" *ns*)
(tst)
Run Code Online (Sandbox Code Playgroud)

感谢阅读,马库斯

cgr*_*and 7

实际上你的代码碰巧使用Clojure> 1.0但不依赖于它!每个顶级表单都被编译然后执行:

(ns xyz) ; compiled with current ns / exec sets the current ns to xyz
(do ; the whole form is compiled inthe current ns (xyz) so it defines xyz/tst
  (ns abc)
  (prn *ns*)
  (defn tst[] (prn "test" *ns*)))
; the form above is executed: it sets the new current ns 
; and the value for xyz/tst

(prn "after" *ns*) ; we are in abc
(tst) ; abc/tst doesn't exists
Run Code Online (Sandbox Code Playgroud)

在clojure> 1.0中,顶级是"展开",所以你的代码现在相当于:

(ns xyz)
; (do
(ns abc)
(prn *ns*)
(defn tst[] (prn "test" *ns*));)

(prn "after" *ns*)
(tst)
Run Code Online (Sandbox Code Playgroud)