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.