Was just musing some more - the Clojure Java API was added pretty late 
(~1.6 or 1.7). I wonder if

1) changing the Java Clojure API to ensure a certain binding context and
2) changing the main() method to invoke the Clojure function through the 
Java Clojure API

would be a good end game. Would need a lot more analysis.

On Wednesday, June 21, 2017 at 8:52:48 PM UTC-5, Alex Miller wrote:
>
>
>
> 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