I apologize in advance for the length of this post, but I need to start with an example before my question will make sense.
I have been looking at the inner workings of Clojure's Java interop, and I wondered how it would handle classes with a field and method with the same name, like this: public class InteropTest { public String str = "Field"; public String str() { return "0-arg Method"; } } Granted, duplicating names like this is bad practice, but Java allows this and Clojure should provide access to both the field and the method. Using Clojure compiled from a git master snapshot today, I first create an instance of InteropTest: Clojure 1.2.0-master-SNAPSHOT user=> (import InteropTest) InteropTest user=> (def x (InteropTest.)) #'user/x As noted in the docs, access to str resolves to the 0-arg method: user=> (.str x) "0-arg Method" But I see in Compiler.java that the field can still be accessed by using a keyword instead of a symbol: user=> (. x :str) "0-arg Method" user=> (. ^InteropTest x :str) "Field" This only seems to work when the type hint is included. However, the value of this field access expression depends on how it is used. It doesn't work with def: user=> (def field (. ^InteropTest x :str)) #'user/field user=> field "0-arg Method" It does work as a function argument: user=> (defn okay [x] x) #'user/okay user=> (okay (. ^InteropTest x :str)) "Field" ...unless the function name happens to start with "def": user=> (defn defective [x] x) #'user/defective user=> (defective (. ^InteropTest x :str)) "0-arg Method" The reason for this perplexing behavior is Clojure's clojure.lang.Compiler#analyze method, which is part of the evaluation process. Given an expression list expr, this method wraps it with (fn* [] expr), compiles it (indirectly calling expr.emit()), then runs it; however, if the first form in the list is a symbol that starts with "def", it instead calls expr.eval(). So with that long-winded introduction out of the way, here's my question: why is eval needed? Looking through the expression types in Compiler.java, I see some expression classes (including InstanceFieldExpr and InstanceMethodExpr, which handle field access and method invocation) that appear to have subtle differences between the emit() and eval() methods. Apart from my example above, I couldn't find any other actual expressions with differing results, but I wonder if there are others. If eval() could be eliminated, this problem wouldn't happen. - Spencer -- 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