5
votes

So I'm trying to explore Clojure's internals and I've come across something I'm not quite sure I understand:

From the REPL, I can access RT.var("clojure.core","require") just fine (this is supposed to return the var associated with the "require" symbol in the "clojure.core" namespace):

user=> (clojure.lang.RT/var "clojure.core" "require")
#'clojure.core/require

However, if I try to access it in what I thought was the same way (

user=> (clojure.lang.Var/intern (clojure.lang.Namespace/findOrCreate (clojure.lang.Symbol/intern nil "clojure.main")) (clojure.lang.Symbol/intern nil "require"))
java.lang.IllegalStateException: require already refers to: #'clojure.core/require in namespace: clojure.main (NO_SOURCE_FILE:0)

I get an error that require already refers to something that exists. This is very strange because RT.var is the same as Var.intern, except with the arguments converted to a Namespace and Symbol respectively.

static public Var var(String ns, String name){
    return Var.intern(Namespace.findOrCreate(Symbol.intern(null, ns)), Symbol.intern(null, name));
}

I'll do some more digging, but I'm pretty stumped on this one. I've already checked: 1. nil is the same as null 2. I created var2, which returns the namespace argument sent to Var.intern, and var3, which returns the name argument sent to Var.intern. I then pass those two to Var.intern:

user=> (clojure.lang.Var/intern
(clojure.lang.RT/var2 "clojure.main" "require")
(clojure.lang.RT/var3 "clojure.main" "require"))
java.lang.IllegalStateException: require already refers to: #'clojure.core/require in namespace: clojure.main (NO_SOURCE_FILE:0)

Could this be a bug?

2

2 Answers

4
votes

This works fine:

(clojure.lang.Var/intern
 (clojure.lang.Namespace/findOrCreate
  (clojure.lang.Symbol/create "clojure.core"))
 (clojure.lang.Symbol/create "require"))

Symbol/intern works also:

(clojure.lang.Var/intern
 (clojure.lang.Namespace/findOrCreate
  (clojure.lang.Symbol/intern nil "clojure.core"))
 (clojure.lang.Symbol/intern nil "require"))
0
votes

The REPL is just clojure.main, so we can not intern clojure.main/require in a REPL, but clojure.core/require, I think!