Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 373
Ertuğrul Çetin Avatar asked Dec 11 '22 13:12

Ertuğrul Çetin


2 Answers

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)
like image 128
Alex Miller Avatar answered Jan 16 '23 19:01

Alex Miller


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

like image 24
OlegTheCat Avatar answered Jan 16 '23 20:01

OlegTheCat