Search code examples
clojure

How clojure invoke methods in clj file by function invoke defined in interface IFn?


I try to read clojure's compiler source code

I know the main method is in jvm/clojure/main.java

There is also a java file have main method:jvm/clojure/lang/Compile.java

It seems I can not compile the clj files when I want to get the clojure.jar,although by default,the clj files will be compiled.I can remove the "clojure-compile" section in pom.xml,get 1.8M clojure.jar,not the 4.6M clojure.jar.That can work too.I can only compile the java file,without the clj file.

In main.java,It seems clojure will create many default Namespaces,Vars,Symbols

Then it will "invoke" some method defined in .clj file using invoke defined in IFn.java,like this:

in_ns.invoke(USER);
refer.invoke(CLOJURE);
require.invoke(SERVER);
start_servers.invoke(System.getProperties());
REQUIRE.invoke(CLOJURE_MAIN);
MAIN.applyTo(RT.seq(args));

then bang!The clojure can work,I can run (+ 1 1)

but I can't find where the invoke method's implement is.It seem's empty.In Var.java,the interface is implemented like this:

 return fn().invoke(Util.ret1(arg1,arg1=null));

final public IFn fn(){
return (IFn) deref();
}

final public Object deref(){
TBox b = getThreadBinding();
if(b != null)
    return b.val;
return root;
}

The threadbing seems have this:

Var.pushThreadBindings(
        RT.mapUniqueKeys(CURRENT_NS, CURRENT_NS.deref(),
               WARN_ON_REFLECTION, WARN_ON_REFLECTION.deref()
                ,RT.UNCHECKED_MATH, RT.UNCHECKED_MATH.deref()));

anyway,I read the source code times,It seems many data structure have been created,but I don't know how the methods defined in clj file be invoked,even that I can not compile the clj file,keep them only textfile

Can you teach me?Thanks!


Solution

  • It's not very clear what you're trying to achieve. Are you trying to compile Clojure itself from scratch? Are you trying to understand how the Clojure compiler works?

    It also seems you are not starting from the right class. The class in clojure.main is the Clojure REPL itself, not the compiler. In fact, you can launch it from Java:

    $ java -cp /home/denis/.m2/repository/org/clojure/clojure/1.10.0/clojure-1.10.0.jar:/home/denis/.m2/repository/org/clojure/spec.alpha/0.2.176/spec.alpha-0.2.176.jar clojure.main
    Clojure 1.10.0
    user=> (+ 1 2)
    3
    

    There is a reference document on the Clojure compilation process that might be useful: https://clojure.org/reference/compilation. The important thing to remember is right at the beginning of the doc:

    Clojure compiles all code you load on-the-fly into JVM bytecode

    Each time you define a function in the REPL, or load a file, some bytecode is being generated. This will include one or more .class files, and some of those might be classes implementing the IFn interface.