There are a number of tickets concerned with the fact that the set functions in {{clojure.set}} misbehave when passed arguments that are not sets.
This set of issues include CLJ-810, CLJ-1087, CLJ-1682, and CLJ-1954
The functions affected by this are:
- difference
- intersection
- union
- subset?
- superset?
as these are known to produce unexpected results when passed non-set arguments.
Problem
As the above mentioned issues suggest, todays implementation of these functions leads to confusion and erroneous results when called with non-set input. The user is given no warning or indications of the error he's making.
Possible solutions
1. Add a coercion to {{set}} on the arguments said functions
1. Throw an exception when the arguments are not sets
1. Handle this with clojure.spec
1. Leave it as is
Tradeoffs
1. Given CLJ-2362, which makes a call to {{set}} close to a noop, the coercion should not incur much of a performance penalty. It has been argued that the code might even be faster, as type hints can be given and the compiler/jit might make better choices. For the common mistakes (passing vectors/lists instead of sets) it should be backwards compatible
1. Throwing an exception on non-set arguments would break programs which work correctly today (although by chance), such as data.diff.
1. Handling it with clojure.spec seems like a viable option, but again, this would break data.diff if the functions were spec'ed to both receive and return sets.
1. Leaving it as it is, and we will continue to surprise both new and old clojurists.
Evidence of this being a problem
1. The tickets mentioned above seem to indicate that people stumble upon this often enough to file issues
1. https://clojuredocs.org/clojure.set/superset_q#example-5b5acd38e4b00ac801ed9e39