<< Back to previous view

[CLJ-950] Function literals behavior differ from that of fns Created: 08/Mar/12  Updated: 01/Mar/13  Resolved: 08/Mar/12

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Víctor M. Valenzuela Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: reader


((fn [] true)) ; true
(#(true)) ; classcast exception

((fn [])) ; nil
(#()) ; ()

(some (fn [_]_) [nil false 0 1]) ; 0
(some #(%) [nil false 0 1]) ; NPE

Comment by Tassilo Horn [ 08/Mar/12 12:27 PM ]

This is no defect. Function literals must have a function (or macro or special form) as first symbol.
So your examples should be written like so:

user> (#(do true))
user> (#(do))
user> (some #(do %) [nil false 0 1])
Comment by Víctor M. Valenzuela [ 08/Mar/12 2:10 PM ]

It makes sense. However (and correct me if I'm wrong) there should be little problem in making them fully equivalent to fns, resulting in a more concise and consistent API.

Please consider re-opening the issue as a feature request.

Regards - Víctor.

Comment by Tassilo Horn [ 09/Mar/12 1:26 AM ]

The reader docs at http://www.clojure.org/reader say that #() is not a replacement for (fn [] ...). You can't make it more equivalent to fn without making it much harder to understand. Let me explain that with an example.

(defn get-time []

(#(get-time)) ;; What's the result?

What's the result of the funcall above? Clearly, right now, it is the current system time.

So if we decided to allow to write #(true) as an alternative to (constantly true) [which is a varargs fn] or #(do true) [which is a fn of zero args], then valid values of #(get-time) where both the current system time but also the function object for get-time. Functions are values, too.

Ok, one could say that in the case of a function, #(function) is always a call, but it would make it harder to reason about what the code does for not much benefit.

Comment by Víctor M. Valenzuela [ 09/Mar/12 7:56 AM ]

You're right - satisfying my request would require to change the average use of this feature to #((some_fn %1 %2)) rather than just #(some_fn %1 %2), if we wanted #(true) to be valid. Which indeed would be barely handy.

Thank you.

Generated at Fri Mar 27 19:49:45 CDT 2015 using JIRA 4.4#649-r158309.