<div dir="ltr">On Mon, Dec 7, 2015 at 8:32 PM, Kevin Ballard <span dir="ltr">&lt;<a href="mailto:kevin@sb.org" target="_blank">kevin@sb.org</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><u></u>




<div><span class=""><div>On Mon, Dec 7, 2015, at 03:48 AM, Per Melin wrote: </div></span><blockquote type="cite"><div dir="ltr"><div><div><span class="">
<div>Here is one type of mistake that I made long after that I should have known better:<br></div>
</span><div>[snip]<br></div>
</div>
</div>
</div>
</blockquote><div> </div>
<div>If you find yourself in danger of forgetting that a value is optional, you can always adopt a naming convention that makes it apparent. That would have the same effect as requiring a postfix-? on optional identifiers, except that it&#39;s voluntary.<br></div></div></blockquote><div><br></div><div>That would have helped not at all in the example you snipped. But let&#39;s not get hung up on that, I&#39;d rather establish how useful it is to have &lt;, &lt;=, &gt; and &gt;= cover optional values.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div><div></div><span class="">
<div><br></div>
<blockquote type="cite"><div dir="ltr"><div><div><blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div><div> </div>
<div><span>Personally, I find the ability to compare optionals to be very valuable, almost as valuable as the ability to use == with optionals (which I doubt anyone will argue is a misfeature).</span><br></div>
<div> </div>
</div>
</blockquote><div> </div>
<div><div>I have been trying to come up with situations where you would want to compare two values, knowing that one or both may be nil, with &lt;, &lt;=, &gt; or &gt;=. Other than as for sorting, I can&#39;t think of much. I doubt the Swift team explicitly made this possible without good reason, so I must be missing something.<br></div>
<div> </div>
<div>Could you please share some examples? It doesn&#39;t necessarily have to be code, just explain the context where this is valuable.<br></div>
</div>
</div>
</div>
</div>
</blockquote><div> </div>
</span><div>Sorting is a common one. Another example is just cases where I need to compare two numbers and at least one number may have been generated by an optional process. For example:</div></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>
<div> </div>
<div>    if optAry?.count &gt; 3 {<br></div></div></blockquote><div><br></div><div>Instead of:</div><div><br></div><div>    if let count = optAry?.count where count &gt; 3 {</div><div><br></div><div>Which is twice as long, which of course is inconvenient if you do this a lot, and you don&#39;t need the unwrapped value again. A distinct comparison operator for optional values could solve that.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div><div></div>
<div> This can work with non-numeric values too, though usually if I&#39;m comparing non-numeric values with &lt; then I&#39;m doing some variant on sorting, which we&#39;ve already addressed. For example, from my current codebase I find</div>
<div> </div>
<div><p style="margin-top:0px;margin-bottom:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">let</span> sortedJSON = responsesJSON.<span style="color:rgb(61,29,129)">sort</span> { a, b <span style="color:rgb(187,44,162)">in</span></p>
<p style="margin-top:0px;margin-bottom:0px;font-size:11px;line-height:normal;font-family:Menlo">    <span style="color:rgb(187,44,162)">let</span> a_name = a[<span style="color:rgb(209,47,27)">&quot;name&quot;</span>] <span style="color:rgb(187,44,162)">as</span>? <span style="color:rgb(112,61,170)">String</span></p>
<p style="margin-top:0px;margin-bottom:0px;font-size:11px;line-height:normal;font-family:Menlo">    <span style="color:rgb(187,44,162)">let</span> b_name = b[<span style="color:rgb(209,47,27)">&quot;name&quot;</span>] <span style="color:rgb(187,44,162)">as</span>? <span style="color:rgb(112,61,170)">String</span></p>
<p style="margin-top:0px;margin-bottom:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(187,44,162)">return</span><span style="color:rgb(0,0,0)"> a_name?.</span>lowercaseString<span style="color:rgb(0,0,0)"> &lt; b_name?.</span>lowercaseString</p>
<p style="margin-top:0px;margin-bottom:0px;font-size:11px;line-height:normal;font-family:Menlo">}<br></p></div></div></blockquote><div><br></div><div>Instead of:</div><div><br></div><div><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)">  let</span><span style="font-family:Menlo;font-size:11px"> sortedJSON = responsesJSON.</span><span style="font-family:Menlo;font-size:11px;color:rgb(61,29,129)">sort</span><span style="font-family:Menlo;font-size:11px"> { a, b </span><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)">in</span><br><span style="font-family:Menlo;font-size:11px">      </span><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)">let</span><span style="font-family:Menlo;font-size:11px"> a_name = a[</span><span style="font-family:Menlo;font-size:11px;color:rgb(209,47,27)">&quot;name&quot;</span><span style="font-family:Menlo;font-size:11px">] </span><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)">as</span><span style="font-family:Menlo;font-size:11px">? </span><span style="font-family:Menlo;font-size:11px;color:rgb(112,61,170)">String ?? &quot;&quot;</span><br><span style="font-family:Menlo;font-size:11px">      </span><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)">let</span><span style="font-family:Menlo;font-size:11px"> b_name = b[</span><span style="font-family:Menlo;font-size:11px;color:rgb(209,47,27)">&quot;name&quot;</span><span style="font-family:Menlo;font-size:11px">] </span><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)">as</span><span style="font-family:Menlo;font-size:11px">? </span><span style="font-family:Menlo;font-size:11px;color:rgb(112,61,170)">String ?? &quot;&quot;</span><br><span style="font-family:Menlo;font-size:11px;color:rgb(0,0,0)">      </span><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)">return</span><span style="font-family:Menlo;font-size:11px;color:rgb(0,0,0)"> a_name.</span><span style="color:rgb(112,61,170);font-family:Menlo;font-size:11px">lowercaseString</span><span style="font-family:Menlo;font-size:11px;color:rgb(0,0,0)"> &lt; b_name.</span><span style="color:rgb(112,61,170);font-family:Menlo;font-size:11px">lowercaseString</span><br><p style="margin-top:0px;margin-bottom:0px;font-size:11px;line-height:normal;font-family:Menlo">  }<br></p><br></div><div>Which I think anyone can accept (except that I find ?? to be an eyesore, but that is a different topic.)<br></div><div><br></div><div>Please note that I&#39;m absolutely not arguing for the suggestion that started this thread. I just want to understand if it really is necessary to overload all the comparison operators for (T?, T?) in the first place.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div><div><p style="margin-top:0px;margin-bottom:0px;font-size:11px;line-height:normal;font-family:Menlo"></p><div> (although were I to rewrite this code I&#39;d switch to using caseInsensitiveCompare() as lowercaseString is needlessly allocating a new string, but it demonstrates the idea)</div>
<div> </div>
<div>I know somewhere in another project I used &lt; with optionals to great effect for a non-sorting purpose, but I don&#39;t remember where to find it anymore.<br></div>
<div> </div>
<div>In general, my feeling here is that supporting == and &lt; on optionals is just a specific case of a generally desired property that is Equatable and Comparable should be supported on all types that are simple wrappers around existing Equatable/Comparable types. I know this isn&#39;t well-defined, but I mean that since Optional is really just taking the set of values for a type and adding one additional value, if the type is Comparable/Equatable, there&#39;s an obvious way to define this new inhabiting value as being Comparable/Equatable with the type, and so it should be done. Similarly, I think that if I have a tuple (T, U) where both T and U are Comparable/Equatable, the tuple itself should be (where the Comparable implementation compares the T value first, and if it&#39;s equal then compares the U value). And any larger tuple where every component element is Comparable/Equatable should also be Comparable/Equatable. I should also be able to opt-in to this kind of automatic Comparable/Equatable generation for structs. I should also be able to get this on other enums where only one enum variant has associated values, and the associated values are comparable/equatable (i.e. a generalization of Optional).<span class=""><font color="#888888"><br></font></span></div><span class=""><font color="#888888">
</font></span></div><span class=""><font color="#888888">
<div> </div>
<div>-Kevin</div>
</font></span></div>

</blockquote></div><br></div></div>