<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent questions tagged sorted-set</title>
<link>https://ask.clojure.org/index.php/tag/sorted-set</link>
<description></description>
<item>
<title>Somewhat confusing sorted-set behavior</title>
<link>https://ask.clojure.org/index.php/11409/somewhat-confusing-sorted-set-behavior</link>
<description>&lt;p&gt;Just ran into some interesting behavior with &lt;code&gt;sorted-set&lt;/code&gt;. Namely, the contract to the user for a normal &lt;code&gt;set&lt;/code&gt; is &lt;code&gt;nil&lt;/code&gt; when the element doesn't exist. However, with &lt;code&gt;sorted-set&lt;/code&gt;, the call will throw if the comparator doesn't gracefully handle the type. The &lt;em&gt;reason&lt;/em&gt; makes sense (the comparator requires the ability to sanely compare elements), but the interface is somewhat confusing in the &quot;no membership&quot; case since we know that the element doesn't exist in the set if its type can't be compared by default. &lt;/p&gt;
&lt;p&gt;In other words, I guess I'm proposing that a sane default behavior for a sorted-set using the default comparator should be &lt;code&gt;nil&lt;/code&gt; rather than &lt;code&gt;throw&lt;/code&gt; when the type cannot be compared, in order to allow &lt;code&gt;nil&lt;/code&gt;-punning. &lt;/p&gt;
&lt;p&gt;As an example, this case was encountered when the form was passed to a keyword function &lt;code&gt;(:foobar form)&lt;/code&gt;, which allows nil-punning on a lot of other collections. Here's a small snippet:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;`&lt;/code&gt;&lt;br&gt;
user&amp;gt; (def normal #{&quot;0000&quot;})&lt;/p&gt;
&lt;p&gt;;; =&amp;gt; #'user/normal&lt;/p&gt;
&lt;p&gt;user&amp;gt; (def sorted-version (sorted-set &quot;0000&quot;))&lt;/p&gt;
&lt;p&gt;;; =&amp;gt; #'user/sorted-version&lt;/p&gt;
&lt;p&gt;user&amp;gt; normal&lt;/p&gt;
&lt;p&gt;;; =&amp;gt; #{&quot;0000&quot;}&lt;/p&gt;
&lt;p&gt;user&amp;gt; sorted-version&lt;/p&gt;
&lt;p&gt;;; =&amp;gt; #{&quot;0000&quot;}&lt;/p&gt;
&lt;p&gt;user&amp;gt; (:foobar normal)&lt;/p&gt;
&lt;p&gt;;; =&amp;gt; nil&lt;/p&gt;
&lt;p&gt;user&amp;gt; (:foobar sorted-version)&lt;/p&gt;
&lt;p&gt;Execution error (ClassCastException) at user/eval246355 (form-init59552761865518221.clj:8123).&lt;br&gt;
class java.lang.String cannot be cast to class clojure.lang.Keyword (java.lang.String is in module java.base of loader 'bootstrap'; clojure.lang.Keyword is in unnamed module of loader 'app')&lt;br&gt;
&lt;code&gt;`&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I think my options for handling this are either try/catch or write a custom comparator, and both seem a little wonky :) &lt;/p&gt;
&lt;p&gt;I'm probably missing something, but thought it was interesting anyway :) &lt;/p&gt;
</description>
<category>Collections</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11409/somewhat-confusing-sorted-set-behavior</guid>
<pubDate>Thu, 23 Dec 2021 12:22:35 +0000</pubDate>
</item>
</channel>
</rss>