Clojure 1.9.0-alpha10: Semantic mismatch: any? vs not-any?

307 views
Skip to first unread message

Alan Thompson

unread,
Jul 11, 2016, 2:01:52 PM7/11/16
to clo...@googlegroups.com, cloju...@googlegroups.com
In clojure we are used to shortcuts involving not:

(when-not x ...)         => (when (not x) ...)
(if-not x ...)           => (if (not x) ...)
(not-every? pred coll)   => (not (every? pred coll))
(not-any? pred coll)     => (not (some pred coll))

However, the new function clojure.core/any? breaks this semantic pattern:

​> ​
(doc clojure.core/any?)
-------------------------
clojure.core/any?
([x])
  Returns true given any argument.

​> ​
(doc clojure.core/not-any?)
-------------------------
clojure.core/not-any?
([pred coll])
  Returns false if (pred x) is logical true for any x in coll,
  else true.

​These two functions are not only unrelated to each other, but they don't even accept the same number or type of arguments.  Moreover, ​there is an even more surprising property:

> (clojure.core/any? nil)
true

I would have bet money that, at least for nil, the result would not have been true.
Given the significant prior conventions in Clojure​ for functions like some, every?, *-not, not-*, and also the general handling of nil, it seems that the new any? function is bound to cause much confusion & consternation, especially among people learning Clojure.  

Given the degenerate definition:

> (source clojure.core/any?)
(defn any?
  [x] true)

would it not be simpler and more instinctive to rename the function clojure.core/true:

(defn clojure.core/true
  [x] true)

We could then have code with the obvious result:

(true 1)     => true
(true "hi")  => true
(true [])    => true
(true nil)   => true

I believe that such a change would help to keep Clojure in line with users instincts and assumptions, as well as past Clojure practices.  I have often felt that one of the most important principles in any sort of software development is adherence to the Principle of Least Astonishment.

Alan



On Mon, Jul 11, 2016 at 7:28 AM, Alex Miller <al...@puredanger.com> wrote:

1.9.0-alpha10 includes the following changes since 1.9.0-alpha9:

- NEW clojure.core/any? - a predicate that matches anything. any? has built-in gen support. The :clojure.spec/any spec has been removed. Additionally, gen support has been added for some?.



 

Alex Miller

unread,
Jul 11, 2016, 3:02:32 PM7/11/16
to Clojure Dev, clo...@googlegroups.com

On Monday, July 11, 2016 at 1:01:52 PM UTC-5, Alan Thompson wrote:
In clojure we are used to shortcuts involving not:

(when-not x ...)         => (when (not x) ...)
(if-not x ...)           => (if (not x) ...)
(not-every? pred coll)   => (not (every? pred coll))
(not-any? pred coll)     => (not (some pred coll))


The latter two are collection predicates, not simple value predicates, so I don't think they can actually relate closely to any?.
 
However, the new function clojure.core/any? breaks this semantic pattern:

​> ​
(doc clojure.core/any?)
-------------------------
clojure.core/any?
([x])
  Returns true given any argument.

​> ​
(doc clojure.core/not-any?)
-------------------------
clojure.core/not-any?
([pred coll])
  Returns false if (pred x) is logical true for any x in coll,
  else true.

​These two functions are not only unrelated to each other, but they don't even accept the same number or type of arguments. 

Well, there are only so many words. As it happens any? is best name for this function.
 
Moreover, ​there is an even more surprising property:

> (clojure.core/any? nil)
true

I would have bet money that, at least for nil, the result would not have been true.

The doc string seems quite clear. The English sense of "any" also seems quite clear and the distinction vs "some?" is the important one. 
 
Given the significant prior conventions in Clojure​ for functions like some, every?, *-not, not-*, and also the general handling of nil, it seems that the new any? function is bound to cause much confusion & consternation, especially among people learning Clojure.  

Given the degenerate definition:

> (source clojure.core/any?)
(defn any?
  [x] true)

would it not be simpler and more instinctive to rename the function clojure.core/true:

(defn clojure.core/true
  [x] true)


I don't like the use of true. "any?" is asking a question about an input value. "true" is a statement about the result, which totally misses the point of this function. Also, it shadows an existing literal token in the language.

We have no plans to change the name of this function.

Tassilo Horn

unread,
Jul 13, 2016, 6:15:14 AM7/13/16
to Alex Miller, Clojure Dev, clo...@googlegroups.com
Alex Miller <al...@puredanger.com> writes:

Hi Alex,

> Well, there are only so many words.

Of course, but I also think that any? is absolutely certain to be
confused with some counterpart to every?.

> As it happens any? is best name for this function.

What about "anything?". To me (as a non-native speaker) that sounds
even better to me, i.e., a function foo has an argument whose value
might be anything.

Bye,
Tassilo

Alex Miller

unread,
Jul 15, 2016, 5:38:57 PM7/15/16
to Clojure, cloju...@googlegroups.com

On Friday, July 15, 2016 at 2:27:56 PM UTC-5, Atamert Ölçgen wrote:

I can't think of a single use case where this function would be useful. I would either inline true instead of a function call, or I would supply (constantly true) if a function is expected.

I am sure it wouldn't be included in core if there wasn't a valid reason. Could you tell me what is this function good for?

It's useful for defining specs.

Alex Miller

unread,
Jul 18, 2016, 4:33:18 PM7/18/16
to Clojure, cloju...@googlegroups.com, al...@puredanger.com
Please, let's end the discussion on this - it's not up for debate.

On Monday, July 18, 2016 at 3:28:05 PM UTC-5, Logan Buckley wrote:
FWIW, I was not aware of `any?` when I read this thread, and I found its semantics confusing -- I think `anything?` would be much clearer. `anything?` also seems more obviously useful for defining specs (e.g. a function can take _anything_ as an argument). It seems usual in Clojure for scalar predicates such as int?, string?, rational? etc to have noun or adjective names, and collection predicates such as every? to have determiners such as every, some, any as names.

Logan
Reply all
Reply to author
Forward
0 new messages