On Wednesday, June 21, 2017 at 6:09:43 PM UTC-5, Didier wrote:
>
> Great breakdown.
>
> 1. "compile and bootstrap yourself through gen-class" means: you generate 
>> a class and then invoke the main() method of that class
>>
>
> I'd go further then just calling main. So I mean you generate a class, and 
> every function call from Java using the generated class should be executed 
> as if it were executed through clojure.main, so with the bindings set and 
> inside the user namespace.
>

I do not think you should treat clojure.main as the gold standard. 
clojure.main is a helper program and it makes some choices that may or may 
not be what every program wants. There is nothing special about the "user" 
namespace for example. Other repls choose other things (pretty sure the 
boot repl uses boot.user example). Likewise, there's nothing special about 
the set of things clojure.main chooses to bind on startup - lein, boot, and 
other tools make different choices. If anything, I'd say #2 is what you 
should consider the most canonical case.
 

>  
>
>> 2. "loaded at runtime" means: you (presumably) start the REPL, load a 
>> namespace (either from a source file or a class file), then invoke the 
>> -main function
>>
>
> Correct. It's the case of a non AOT compiled namespace being loaded from 
> one of the many (load) functions of Clojure. Such as:
>
> (load "dda/main")
> (dda.main/-main)
>  
>
>> 3. "bootstrapped through clojure.main" means: you invoke clojure.main (a 
>> compiled program provided with Clojure) with the -m arg specifying a 
>> namespace. This will start the Clojure runtime, load the namespace, then 
>> invoke the -main function
>>
>
> Correct.
>  
>
>> 4. "bootstrapped through lein" means: I assume this is "lein run" with a 
>> :main set or "lein run -m" but I think lein supports specifying a namespace 
>> or a function in a namespace or a class with a main() method. Depending 
>> which of those you're doing, this is like similar to either #1 or #2 and 
>> here lein is effectively doing similar work as #3.
>>
>
> Correct, yes internally lein delegates to clojure.main I believe.
>

No, I don't think lein uses clojure.main at all.
 

>  
>
>> 5. There is a Clojure Java API (http://clojure.github.io/clojure/javadoc/), 
>> but I'm not sure if you are actually referring to this or something else. 
>> Doing so would basically mean going through that API to do the same thing 
>> as #2. 
>>
>
> I am talking about that API. I believe it uses RT under the hood, and ends 
> up doing the same thing that #1 does. So in my test, if you did:
>

This is actually the same as #2, not #1. It's not making an interop call, 
it's invoking a var function, just like any other Clojure call. 

>
> IFn require = Clojure.var("dda.main", "-main");
> require.invoke();
>
> This will run inside "clojure.core", and will not have any of the default 
> bindings set available.
>
> I think if I were to restate your suggestion, I would say that a 
>> genclass-compiled main entry point should initialize the Clojure runtime 
>> and invoke the code in a binding as if it were being invoked from other 
>> Clojure code. I can see some logic in that (although that then also affects 
>> #3 and #4 as they go through this code too).
>>
>
> Ya, arguably, I wonder why the clojure runtime doesn't initialize the 
> bindings and sets the namespace to 'user before delegating execution back 
> to user code.
>

Again, there is nothing special about user and I wouldn't get hung up on 
that. It does seem like it would be reasonable to set up a binding context 
for *ns* though so it's set!-able - that's the thing that's missing.
 

> If it did, then every invocation of Clojure from Java would always be 
> bootstrapped in a similar way, and run under an equal context. Clojure.main 
> wouldn't need to do it anymore.
>
> But there might be a good reason for not doing that inside the clojure 
> runtime. In which case, it still leaves open the question of should clojure 
> invocations through a generated class, and invocations from the Clojure API 
> mimic the bootstrapping of clojure.main?
>

I would say, no. :) But it might be reasonable to mimic a Clojure function 
invocation that has a binding for *ns*. If you want to file a ticket, I'm 
happy to think about it more.
 

>
> P.S.: I also know that in practice, this has not caused that many issues, 
> due to the fact that Clojure is now many years old, and I've never heard of 
> other people complain about the discrepancies between generated classes and 
> the clojure API versus clojure.main. So I don't think its a pressing issue, 
> but I still feel it could be worth a thought.
>
>>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to