[CLJ-1147] Threading macro (->) does not permit inline function declarations Created: 14/Jan/13 Updated: 26/May/13
|Affects Version/s:||Release 1.5|
(-> [1 2 3] (fn [args] apply + args))
CompilerException java.lang.Exception: Unsupported binding form: 1, compiling:(NO_SOURCE_PATH:1:13)
The expression is expanded to:
(fn [1 2 3] [args] apply + args)
If this is intended behaviour then at the least the compiler error message is confusing. It would be preferable if the -> macro checked for (fn..) before treating a form as a sequence and injecting the argument.
|Comment by Andy Fingerhut [ 15/Jan/13 12:56 AM ]|
Note that this works as you might have hoped:
(-> [1 2 3] ((fn [args] (apply + args))))
because it expands into:
((fn [args] (apply + args)) [1 2 3])
Your suggestion that -> check for (fn ...) before treating it as a sequence and injecting the argument leaves open the question: Why only (fn ...) should be treated specially? Why not (let ...), (for ...), (doseq ...), etc? And if you go that far, how do you decide what should be allowed and what not?
|Comment by Gabriel Horner [ 17/May/13 2:56 PM ]|
I agree with Andy, that it's not realistic suggestion to check for fn,let,etc. Perhaps a doc fix would help here but I'm not sure if we just want to call out (fn ...). I'd recommend closing this unless Stephen speaks up.
|Comment by Stephen Nelson [ 19/May/13 10:29 PM ]|
I'm happy with Andy's synopsis of the problem, and it's reasonable not to change the behaviour of the threading macro specifically for (fn..).
However, this is a mistake that I'm sure many others make/have made and it's hard to diagnose what is going wrong without dumping interpreted form – hardly a reasonable expectation for a novice user.
Before closing this issue, I'd like to see improved failure reporting, such as causing the threading macro to throw a compile error or warning if passed a raw (unwrapped) function declaration (are there legitimate use cases this would affect?).
|Comment by Gary Fredericks [ 26/May/13 2:21 PM ]|
Throwing an error on (-> [1 2 3] (fn ...)) would certainly affect any perverse individual using a local redefinition of 'fn.
I think the best that can be done here is a mention in the docstring.