Welcome! Please see the About page for a little more info on how this works.

+2 votes
ago in Clojure by

Shuffling an empty collection is fine:

user> (shuffle [])
[]

But shuffling nil results in NPE:

user> (shuffle nil)
Execution error (NullPointerException) at java.util.ArrayList/<init> (ArrayList.java:181).
Cannot invoke "java.util.Collection.toArray()" because "c" is null

Why is it not nil-safe like other seq ops?

ago by
Because the first thing it does is pass its argument (assumed to be a `java.util.Collection`) to the `ArrayList` constructor: https://github.com/clojure/clojure/blob/fb22fd778a272b034684a4ee94509552b46ee8a9/src/clj/clojure/core.clj#L7471
ago by
Well yes, this much is clear - I am asking whether this is intended behavior or just accidental. I for one found it to be surprising.
ago by
Ah, that's a different question. Looks to have been decided ~15 years ago: https://github.com/clojure/clojure/blame/fb22fd778a272b034684a4ee94509552b46ee8a9/src/clj/clojure/core.clj#L7471 --- I'd hesitate to guess whether it was intended or accidental.

1 Answer

0 votes
ago by

nil is a reliable pun for an empty seq, but shuffle is not a seq operation. It is a collection operation.

ago by
Hm, how do you determine whether something is a collection operation versus a seq operation? Sure, the docstring of `shuffle` says "Return a random permutation of coll" and the argument is also called `coll` but the same is true for say `filter`. Also, calling `shuffle` with a non-nil (lazy) seq works fine, too.

Aha, now I see that the argument for `shuffle` is tagged with `java.util.Collection` but that's more like an implementation detail, no? Seems inconsistent to me to not also accept `nil` here due to the above.
...