My Increasing Frustration with Clojure
&gt; And the namespace is completely riddled with bugs. union returns duplicates if some of the inputs are lists instead of sets depending on their length.<p>to be clear I assume he is taking about this:<p>```
try-spec.core=&gt; (clojure.set&#x2F;union [1,2] [1,2])
[1 2 1 2]
```<p>Though im not sure what &quot;depending on their length means&quot;.<p>&gt; for the above bugs there are two possible fixes: raise an IllegalArgumentException if anything other than sets are provided<p>Isn&#x27;t this an argument for types? Wont this type of problem be prolific in any dynamic language? What is the union of anything besides sets?<p>&gt; coerce lists and vectors to sets before continuing<p>This only works for very similar data. How do you coerce a map into a set? Is it based on keys or values? What about a string? is it based on the whole string or the characters. I loaded up python3 to see how it was handled...<p>```
In [7]: set([&quot;hello&quot;]).union([&quot;hello&quot;])
Out[7]: {&#x27;hello&#x27;}```<p>is that what you would expect? Maybe. But honestly it should have thrown an error imo. Python is just skirting the issue. A set needs a hashable type. A list isn&#x27;t one because its mutable. So python  knew you &quot;meant&quot; a set of the items in the list... It throws up its hands if you force the issue further:<p>```
In [8]: x = [1,2,3]<p>In [9]: set(x)
Out[9]: {1, 2, 3}<p>In [10]: set([x])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
&lt;ipython-input-10-0b079714f02c&gt; in &lt;module&gt;()
----&gt; 1 set([x])<p>TypeError: unhashable type: &#x27;list&#x27;```<p>The problem is that we have handed the union function the wrong type of arguments. That it fails in further down stream is the trade off we make with dynamic languages. The community seems to admit the trade off and alleviate it with things like clojure.spec. Im not mental equipped to argue type theory here. But i suppose i feel this is an _ancient_ argument and saying its a &quot;bug&quot; seems simplistic.<p>&gt; How you define getting the wrong type with nonsense values counts as “working” is beyond me. Is it just because it doesn’t throw an Exception? Anyone here prefer bad data instead of exceptions when dealing with functions like this? I doubt it.<p>This is maybe the deeper problem. You would expect union to fail given the wrong types. Sure the failure wont be a type error but it will be contained inside the function. Leaking out the wrong data means its harder to debug. I&#x27;m generally curious how and why set would work on lists at all.<p>As to the rest of the arguments made here. I don&#x27;t know enough to hazard a guess. But i would appreciate any feedback on my interoperation of the above situation.