I'm struggling with a basic feature of how macros behave. I understand how the problem arises, and I can cobble together my own fix in the specific places where it's causing me trouble, but it seems like a prettier, more general solution would be desirable. Below is a brief transcript demonstrating the problem.
user> (defmacro call [f arg] `(~f ~arg)) #'user/call user> (let [f inc] (.intValue (f 10))) Reflection warning, NO_SOURCE_FILE:1 - reference to field intValue can't be resolved. 11 user> (let [f inc] (.intValue ^Integer (f 10))) 11 user> (let [f inc] (.intValue ^Integer (call f 10))) Reflection warning, NO_SOURCE_FILE:1 - reference to field intValue can't be resolved. 11 I want to typehint the return value of f, so I put metadata on the form representing a call to it. But if a macro gets involved, there's an "intervening" form that ignores its metadata and returns a new list of '(f 10) with no metadata. Thus the compiler has no idea I ever wanted to give it a hint about the type. There are two solutions that are simple enough for me to apply: (1) At the call site I can bind the result of (call f 10) to a local named i and then put the typehinting metadata on that (2) I can edit the call macro to return a form with the right metadata: (defmacro call [f arg] (with-meta `(~f ~arg) (meta &form))) Both of these work, but they seem awful. If the language specifies you're supposed to be able to typehint expressions as well as named bindings, it's both unintuitive and quite inconvenient that most macros do not "respect" this behavior by default. And many macros I don't have enough control over to make this change. For example, the whole issue arose when I was trying to hint the result of a (for ...) as a java.util.List. It ignores my metadata and returns a new form; and I certainly can't go edit its source, so instead I have to bind the result in a let, for no reason other than to typehint it. It seems to me that it would be nice to have macros automatically include, on their result forms, the metadata from their input &form. Of course, macros may wish to add metadata as well, so the two maps should probably be merged. However, there are certainly some problems with this approach: for example if a macro wants to return something that can't suppport metadata (like an Integer), the compiler needs to be careful not to try to include it. So I'm hoping the community can comment on whether this feature would be useful, or whether there are fundamental problems with it that I haven't foreseen. Is there a reason this can't make it into a future version of Clojure? -- 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