On Fri, Oct 16, 2009 at 8:28 AM, Christophe Grand <[email protected]> wrote: > Hi, > > On Wed, Oct 14, 2009 at 8:50 PM, Manuel Woelker <[email protected]> > wrote: >> >> Hi all, >> >> after digging around a bit in the clojure code, trying to get the >> compile to work, I found out that classes used by the compiled code >> actually classloaded by the compiler. >> >> I can totally get behind the idea that code is data. But in this case >> data is considered code, and is immediately executed. This leads to >> all kinds of fun. > > Like to have to specify to use headless mode when compiling something that > uses swing/awt on a headless server. > > >> I guess one way to achieve this would be to use "Class handles", >> instead of raw Class objects. Depending on situation these class >> handles could either delegate to Class instances or use asm to get the >> required information. This might be a best of both worlds solution. > > > If I understand both correctly what you propose and how the compiler works > right now, it's one step but I think it won't be enough: you'll have at > least to lazily initalize vars (or come up with a clever static analysis) to > load only the required fns to support the macro. > In the following case, how can you know that the class backing #'a must be > loaded but not the on backing #'b? And what if #'c is not used anywhere? > (defn a []) > (defn b []) > (defmacro c [] (a)) > > Ditto for used/required namespaces: you'll have to short-circuit their inits > to not trigger many useless class loadings.
Yes, some sort of lazy-loading scheme for vars might be necessary. It might be possible to keep a per namespace "symbol table" that can resolve the required functions as needed. > Preventing java classes loading (and thus their init) requires to track vars > inits because when you compile eg (defn bar[n] (Foo/baz n)), a class (say > fn$42.class) is generated for (fn [n] (Foo/baz n)) (and it's where you > propose to not load Foo) but immediately after fn$42 is instantiated (thus > effectively loading Foo) and the resulting instance is put in #'bar. I am not a 100% sure about some of the implementation details of the clojure compiler, so please correct me if I'm wrong on the following. The assignment of an instance of fn42 to #'bar should happen in the namespace initializer, which itself is a method on the init class of that namespace. So again at AOT compile time there is no need to actually load the class fn42. The code generation could use a class handle to fn42 instead. This all assumes that namespaces are not instantiated at AOT compile time, another detail I am not totally clear on. Maybe their are other, more straight-forward and/or cleaner implementation strategies for side effect free AOT compilation that escape my limited understanding of the clojure internals. I am eager to hear about alternative proposals. If anyone thinks side-effect free AOT compilation in clojure is impossible or undesirable I am very interested to hear these thoughts as well. Cheers and thanks for patience with a clojure newcomer - Manuel Woelker --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to [email protected] Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---
