This issue is a subtle one.  I do find it interesting that all vars are 
created and mapped to their namespace in the initN() (where N is 0 though 
whatever) methods.
However, other top-level function calls happen in the load() method.  All 
of this runs in the clinit of the class though.  

I'd really like to understand/get an explanation of the reason why some 
things go in the initN() methods vs what goes in the load() method.  I 
think it looks mostly clear that initN() methods just assign values to 
static fields of the class and everything else goes in load().  That may be 
an oversimplification though.

The thing that really surprised me on this one is that the order of 
operations in the AOT class is not really the same as the order you'd 
expect the compiler events to occur.  I do agree that multiple `def`s of 
the same var is probably a bad pattern.

On Wednesday, December 30, 2015 at 12:02:35 PM UTC-6, Nicola Mometto wrote:
>
> While it's true that AOT has many issues, it's getting better release 
> after release and this is definitely a bug. 
> I don't understand why you wouldn't expect this to work, you *should*. 
>
> OP: can you open a ticket for this bug? I'd love to have a look at this 
> and try to fix it. 
>
> > On 29 Dec 2015, at 17:28, Stuart Sierra <the.stua...@gmail.com 
> <javascript:>> wrote: 
> > 
> > AOT-compilation breaks almost any code that tries to redefine Vars. I 
> wouldn't expect this to work. 
> > —S 
> > 
> > 
> > On Monday, December 28, 2015, wparker30 wrote: 
> > I have found what appears to be a bug in AOT-compiled Clojure when 
> ns-unmap is used.  I have the following reduced case: 
> > 
> > (ns unmap-test.core) 
> > 
> > (def a :test-1) 
> > 
> > (ns-unmap 'unmap-test.core 'a) 
> > 
> > (def a :test-2) 
> > 
> > It turns out that a is not resolvable when this namespace is loaded. 
>  When I looked at the compiled bytecode, 
> > it appears that the following operations occur: 
> > 
> > 1. A call to RT.var withe 'unmap-test.core and 'a returns a Var, which 
> is bound to a constant. 
> >   This var is added to the namespaces's mapping during this call. 
> > 2. Same as 1. 
> > 3. The var from 1 is bound to :test-1. 
> > 4. ns-unmap is called. 
> > 5. The var from 2 is bound to :test-2. 
> > 
> > Disclaimer: This is the first time I have had occasion to look directly 
> at bytecode and I could be missing something. 
> > 
> > The basic problem here is that the var is accessible from the load 
> method, but when step 5 executes the var is no longer 
> > accessible from the namespace mappings.  Thus, the root of the Var is 
> set to :test-2, but that Var is not mapped from the namespace. 
> > This works when there is no AOT compilation, as well as when I use 
> > 
> > (ns unmap-test.core) 
> > 
> > (def a :test-1) 
> > 
> > (ns-unmap 'unmap-test.core 'a) 
> > 
> > (intern 'unmap-test.core 'a :test-2) 
> > 
> > I realize that creating defs, unmapping them, and then recreating them 
> is generally poor practice in Clojure. 
> > We have an odd case in that we need to have an interface and a Var of 
> the same name in the same namespace.  Simply 
> > doing definterface and then def causes a compilation failure: 
> > 
> > user=> (definterface abc) 
> > user.abc 
> > user=> (def abc 1) 
> > CompilerException java.lang.RuntimeException: Expecting var, but abc is 
> mapped to interface user.abc, 
> compiling:(/private/var/folders/3m/tvc28b5d7p50v5_8q5ntj0pmflbdh9/T/form-init4734176956271823921.clj:1:1)
>  
>
> > 
> > Without going into too much detail, this is basically a hack to allow us 
> to refactor our internal framework code 
> > without immediately changing a very large amount of downstream consumer 
> code.  We get rid of the usage of the interface during macroexpansion, 
> > but it still needs to exist on the classpath so it can be imported by 
> downstream namespaces.   
> > There are a number of other ways to accomplish this, so it isn't a 
> particularly big problem for us, but I thought the issue was worth raising. 
> > This was just the first thing I tried and I was surprised when it didn't 
> work. 
> > 
> > Note that I used the 1.8.0 RC4 version of Clojure in my sample project, 
> but I had the same behavior on 1.7.0. 
> > 
> > Relevant links: 
> > 
> > 1. Bytecode for the load method of the init class: 
> https://gist.github.com/WilliamParker/d8ef4c0555a30135f35a 
> > 2. Bytecode for the init0 method: 
> https://gist.github.com/WilliamParker/dc606ad086670915efd9 
> > 3. Decompiled Java code for the init class.  Note that this does not 
> completely line up with the bytecode as far as I can tell, 
> > but it is a quicker way to get a general idea of what is happening than 
> the bytecode. 
> > https://gist.github.com/WilliamParker/4cc47939f613d4595d94 
> > 4. A simple project containing the code above: 
> https://github.com/WilliamParker/unmap-test 
> > Note that if you try it without AOT compilation the target folder with 
> any previously compiled classes should be removed. 
> > 
> > I may or may not be able to respond to any replies before next week; I 
> apologize for any delayed responses. 
> > 
> > -- 
> > You received this message because you are subscribed to the Google 
> > Groups "Clojure" group. 
> > To post to this group, send email to clo...@googlegroups.com 
> <javascript:> 
> > Note that posts from new members are moderated - please be patient with 
> your first post. 
> > To unsubscribe from this group, send email to 
> > clojure+u...@googlegroups.com <javascript:> 
> > 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+u...@googlegroups.com <javascript:>. 
> > For more options, visit https://groups.google.com/d/optout. 
>
>

-- 
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