<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div>On Mon, Dec 7, 2015, at 12:01 PM, Dmitri Gribenko wrote:<br></div>
<blockquote type="cite"><div dir="ltr"><div><div><div>On Mon, Dec 7, 2015 at 11:48 AM, Kevin Ballard via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt;</span> wrote:<br></div>
<blockquote style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204, 204, 204);border-left-style:solid;padding-left:1ex;"><div><u></u><br></div>
<div><div>I'd really like to see tuples support comparison operators when possible. Eventually they should even conform to the Equatable/Comparable protocols, but that requires tuples being able to conform to protocols at all to begin with.<br></div>
<div>&nbsp;</div>
<div>In the absence of some sort of variadic type parameters, we'd only be able to support the comparison operators on tuples up to some predefined arity. There's precedent in Rust and Haskell for this. Rust defines these operations up to arity 12, Haskell defines them up to arity 15.<br></div>
<div>&nbsp;</div>
<div>Behavior of == should be obvious. Behavior of the ordered comparison operators would work like comparison of strings, where the first element is compared, and if equal, the second element is compared, etc.<br></div>
<div>&nbsp;</div>
<div>This would be implemented using some .gyb code that generates declarations that look something like<br></div>
<div>&nbsp;</div>
<div><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif">func == &lt;A: Equatable, B: Equatable, C: Equatable&gt;(lhs: (A, B, C), rhs: (A, B, C)) -&gt; Bool {</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif">&nbsp;&nbsp;&nbsp; return lhs.0 == rhs.0 &amp;&amp; lhs.1 == rhs.1 &amp;&amp; lhs.2 == rhs.2</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif">}</span><br></div>
<div>&nbsp;</div>
<div><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif">func &lt; &lt;A: Comparable, B: Comparable, C: Comparable&gt;(lhs: (A, B, C), rhs: (A, B, C)) -&gt; Bool {</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif">&nbsp;&nbsp;&nbsp; if lhs.0 != rhs.0 { return lhs.0 &lt; rhs.0 }</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif">&nbsp;&nbsp;&nbsp; if lhs.1 != rhs.1 { return lhs.1 &lt; rhs.1 }</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif">&nbsp;&nbsp;&nbsp; return lhs.2 &lt; rhs.2</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif">}</span><br></div>
<div>&nbsp;</div>
<div><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif">func &gt; &lt;A: Comparable, B: Comparable, C: Comparable&gt;(lhs: (A, B, C), rhs: (A, B, C)) -&gt; Bool {</span><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif"></span><br></div>
<div><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif">&nbsp; &nbsp; if lhs.0 != rhs.0 { return lhs.0 &gt; rhs.0 }</span><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif"></span><br></div>
<div><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif">&nbsp; &nbsp; if lhs.1 != rhs.1 { return lhs.1 &gt; rhs.1 }</span><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif"></span><br></div>
<div><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif">&nbsp; &nbsp; return lhs.2 &gt; rhs.2</span><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif"></span><br></div>
<div><span class="font" style="font-family:menlo, consolas, 'courier new', monospace, sans-serif">}</span><br></div>
</div>
</blockquote><div>&nbsp;</div>
<div>Looks like a good idea to me!&nbsp; Also the &lt;= and &gt;= operators, right?<br></div>
</div>
</div>
</div>
</blockquote><div>&nbsp;</div>
<div>Yeah, and != too. I just skipped them for brevity.</div>
<div>&nbsp;</div>
<blockquote type="cite"><div dir="ltr"><div><div><div>What concerns we with massive code generation is the code size of the core swift library.&nbsp; It would be definitely important to see how much code this adds, depending on the number of tuple elements.<br></div>
</div>
</div>
</div>
</blockquote><div>&nbsp;</div>
<div>Good question. What's the best way to measure this? File size of build/$target/swift-macosx-x86_64/lib/swift/macosx/libswiftCore.dylib (does that even include generic functions)? Or the x86_64/libswiftCore.dylib from the same folder (what's the difference)? Or x86_64/Swift.swiftmodule? Something else?<br></div>
<div>&nbsp;</div>
<blockquote type="cite"><div dir="ltr"><div><div><div>I personally don't see a point in going as high as 12 tuple elements.&nbsp; About 4 or 5 makes sense to me.&nbsp; Given that Swift does not have variadic generics right now, these long tuples have to be defined by someone manually.&nbsp; If one is defining a tuple that is that long, I'd argue that they should be using a custom struct instead.<br></div>
</div>
</div>
</div>
</blockquote><div>&nbsp;</div>
<div>Depends on how much code size it is. I'd rather err on the side of defining it for a higher arity tuple than we expect people to actually use in practice. Just because it's probably a good idea to not point more than a handful of elements in a tuple doesn't mean people will actually stick to that, and it's surprising behavior to have == suddenly break because you added one more (Equatable) value to the tuple. As an example, my coworker recently wrote some code that uses a tuple of 7 elements (as a typedef). It probably should have been a struct, but I think it was originally defined with just 3 or 4 elements and sprouted the others as he worked on it. Granted, this particular tuple wouldn't actually support ==, but I'm sure others have written similarly long tuples.<br></div>
<div>&nbsp;</div>
<div>I'll probably prototype this some time today, and I can produce some measurements of code size at different arities (if I can figure out the best way to measure that).</div>
<div>&nbsp;</div>
<div>-Kevin Ballard</div>
</body>
</html>