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