为什么 Clojure 在创建新的命名空间后不提供标准库?

Why Doesn't Clojure provide standard library after creating new namespace?

我在创建新命名空间后遇到了这个问题。

代码如下:

(create-ns 'my-new-ns)
=> #object[clojure.lang.Namespace 0x7c7c8359 "my-new-ns"]

(in-ns 'my-new-ns)
=> #object[clojure.lang.Namespace 0x7c7c8359 "my-new-ns"]

(reduce + [1 2 3])
CompilerException java.lang.RuntimeException: Unable to resolve symbol: reduce in this context, compiling:(/private/var/folders/pg/bynypsm12nx1s4gzm56mwtcr0000gn/T/form-init1425759900088902804.clj:1:1) 

如您所见,reduce 函数未在 my-new-ns 命名空间中定义。

我应该能够创建新的命名空间,所以 这个问题的最佳解决方案是什么?

P.S:此外,我正在尝试为我的用户创建这些命名空间,以便他们能够在其命名空间中做任何他们想做的事情(这个想法就像一个容器)并在命名空间之间创建隔离.

您的新命名空间需要使用 "standard" 命名空间才能解析其中的名称。文档表明这将是 java.langclojure.lang.Compilerclojure.core.

我建议使用 ns 宏,而不是手动创建命名空间然后切换到它。根据文档:

Sets *ns* to the namespace named by name (unevaluated), creating it if needed.

它还会 load all public varsclojure.core 到新创建的命名空间。

所以,基本上是这样

> (create-ns 'my-new-ns)
> (in-ns 'my-new-ns)
> (clojure.core/refer 'clojure.core)

等于这个

> (ns my-new-ns)

更新:

回答您的问题:来自标准库的符号在新创建的命名空间中不是 refer红色,这就是为什么您不能在没有限定符的情况下访问它们:

> (create-ns 'x)
> (in-ns 'x)
> reduce ;; throws "Unable to resolve symbol"
> clojure.core/reduce ;; works fine

您需要通过调用 (clojure.core/refer 'clojure.core).

手动引用这些符号

我想你应该使用

(ns my-new-ns)

相反。 create-ns 是 low-level 设施。

clojure.core 函数在需要引用以使它们可用于非限定用途方面并不特殊。 ns 宏做了几件事:

  • 创建命名空间 - create-ns
  • 将当前命名空间更改为该命名空间 - in-ns
  • 自动将所有 clojure.core 变量引用到新命名空间中 - refer-clojure

您始终可以使用 qualified 形式的核心函数(不合格只是少打字),所以当您遇到这种情况时,这个简单的调用会让您再次正确:

(clojure.core/refer-clojure)