Ertuğrul Çetin
Ertuğrul Çetin

Reputation: 5231

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

I came across this problem after creating a new namespace.

Here is the code:

(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) 

As you can see reduce function is not defined in my-new-ns namespace.

I should be able to create new namespaces so What would be the best solution for this problem?

P.S: Also, I'm trying to create those namespaces for my users so they will be able to do whatever they want in their namespaces(the idea is like a container) and creating isolation between namespaces.

Upvotes: 4

Views: 305

Answers (4)

Alex Miller
Alex Miller

Reputation: 70201

clojure.core functions are not special in their need to be referred to make them available for unqualified use. The ns macro does several things:

  • creates the namespace - create-ns
  • changes the current namespace to that namespace - in-ns
  • automatically refers all of the clojure.core vars into the new namespace - refer-clojure

You can always use the qualified form of the core function (unqualified is just less typing), so when you get in this situation, this simple call will get you right again:

(clojure.core/refer-clojure)

Upvotes: 6

yangsx
yangsx

Reputation: 11

I guess you are supposed to use

(ns my-new-ns)

instead. create-ns is a low-level facility.

Upvotes: 1

OlegTheCat
OlegTheCat

Reputation: 4513

Instead of creating namespace manually and then switching to it, I'd recommend using ns macro. According to the doc:

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

Also it will load all public vars from clojure.core to newly created namespace.

So, basically this

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

is equal to this

> (ns my-new-ns)

Update:

Answering your question: symbols from standard library are not referred in newly created namespace, that's why you cannot access them without qualifier:

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

You need to refer those symbols manually by calling (clojure.core/refer 'clojure.core).

Upvotes: 5

Vatine
Vatine

Reputation: 21258

Your new namespace needs to use the "standard" namespaces to be able to resolve names in them. The documentation indicates that this would be java.lang, clojure.lang.Compiler and clojure.core.

Upvotes: 1

Related Questions