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}])
#{}