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

0 votes
in Errors by

This code works:

(apply clojure.set/intersection [[1 2 2] [1]])

but this generates an exception "class clojure.lang.PersistentVector cannot be cast to class clojure.lang.IPersistentSet":

(apply clojure.set/intersection [[\f \o \o] [\o]])

I don't understand why (I'm new too Clojure, started learning today).

1 Answer

+3 votes
by
selected by
 
Best answer

The problem is that clojure.set/intersection is defined as:

Return a set that is the intersection of the input sets

That is, it assumes that all of the arguments that you pass in are sets. Which is not your case. You are passing in vectors. Given that the input arguments do not respect the pre-conditions of the function contract, all bets are off with respect to its behaviour.

In fact, your first version also throws the same exception if the second vector doesn't contain any value that is also present in the first one:

user=> (apply set/intersection [[1 2 3] [4]])
Execution error (ClassCastException) at user/eval2082 (REPL:1). class clojure.lang.PersistentVector cannot be cast to class clojure.lang.IPersistentSet

As you can see, it only "works" in a very limited sub-set of scenarios (and by pure chance) when not using sets for the arguments. On the other hand, using sets works as expected:

user=> (apply set/intersection [#{1 2 3} #{4}])
#{}
user=> (apply set/intersection [#{1 2 3} #{1}])
#{1}
user=> (apply set/intersection [#{\f \o} #{\o}])
#{\o}
user=> (apply set/intersection [#{\f \o} #{\a}])
#{}
...