<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><div class="" style="margin: 0px; line-height: normal;"><font class="" style="background-color: rgba(255, 255, 255, 0);">You can replace the proposed statement `which` (another thread), the existing statement `?:` (this thread), and the global function `??` (which is an odd ball) with matching library methods.</font></div><div class="" style="margin: 0px; line-height: normal;"><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font></div><div class="" style="margin: 0px; line-height: normal;"><font class="" style="background-color: rgba(255, 255, 255, 0);">A library method is likely slower than a built in at this stage until the optimiser improves, but a library function:</font></div><div class="" style="margin: 0px; line-height: normal;"><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font></div><div class="" style="margin: 0px; line-height: normal;"><ol class="MailOutline"><li class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">Is documented right in the IDE including code completion, statements aren’t (you don’t see quick help for `for`!)</font></li><li class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">Having a library function allows the use case to be throughly investigated. Is worth while as a language statement? What exact features are useful? EG should `which` support pattern matching, general boolean expressions, or simply be `Equatable` as shown below?</font></li><li class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">It is simpler to implement, maintain, and change a library function that a built-in.</font></li><li class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">There is no need for a keyword.</font></li></ol></div><div class="" style="margin: 0px; line-height: normal;"><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font></div><div class="" style="margin: 0px; line-height: normal;"><font class="" style="background-color: rgba(255, 255, 255, 0);">First `which`:</font></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">// Alternative to introducing `which` statement</span></div><div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">final</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class="">class</span> Which<I: Equatable, R> {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> </span>private</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">var</span> result: <span class="">R</span>?</span></div><p class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"> </span></p><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> </span>private</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">let</span> which: <span class="">I</span></span></div><p class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"> </span></p><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">init</span>(<span class="">_</span> which: <span class="">I</span>) {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">self</span>.<span class="">which</span> = which</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><p class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"> </span></p><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">func</span> match(value: I, <span class="">@noescape</span> matchResult: () <span class="">throws</span> -> R) <span class="">rethrows</span> -> <span class="">Self</span> {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">if</span> <span class="">self</span>.<span class="">result</span> == <span class="">nil</span> && <span class="">self</span>.<span class="">which</span> <span class="">==</span> value {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">self</span>.<span class="">result</span> = <span class="">try</span> matchResult()</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> </span>return<span class=""> </span>self</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><p class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"> </span></p><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">func</span> matchDefault(<span class="">@noescape</span> defaultResult: () <span class="">throws</span> -> R) <span class="">rethrows</span> -> <span class="">R</span> {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">switch</span> <span class="">self</span>.<span class="">result</span> {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">case</span> .None:</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">return</span> <span class="">try</span> defaultResult()</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">case</span> .Some(<span class="">let</span> value):</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">return</span> value</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">}</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">// Demo</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class="">enum</span> Color {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">case</span> Red, Blue, Green</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">}</span></div><div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">// Which with a default value</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class="">let</span><span class=""> i1 = </span><span class="">Which</span><span class="">(</span><span class="">Color</span><span class="">.</span><span class="">Red</span><span class="">) </span>// i = <a dir="ltr" href="tel:16711680" x-apple-data-detectors="true" x-apple-data-detectors-type="telephone" x-apple-data-detectors-result="0">16711680</a></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> .<span class="">match</span>(.<span class="">Red</span>) { <span class="">0xFF0000</span> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> .<span class="">match</span>(.<span class="">Green</span>) { <span class="">0x00FF00</span> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> .<span class="">match</span>(.<span class="">Blue</span>) { <span class="">0x00000FF</span> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> .</span>matchDefault<span class=""> { </span><span class="">0</span><span class=""> }</span></span></div><div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">// Which that throws an error if it defaults</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class="">let</span><span class=""> i2: </span><span class="">Int</span><span class="">! = </span><span class="">Which</span><span class="">(</span><span class="">Color</span><span class="">.</span><span class="">Green</span><span class="">) </span>// i = <a dir="ltr" href="tel:16711680" x-apple-data-detectors="true" x-apple-data-detectors-type="telephone" x-apple-data-detectors-result="1">16711680</a></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> .<span class="">match</span>(.<span class="">Red</span>) { <span class="">0xFF0000</span> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> .<span class="">match</span>(.<span class="">Green</span>) { <span class="">0x00FF00</span> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> .<span class="">match</span>(.<span class="">Blue</span>) { <span class="">0x00000FF</span> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> .</span><span class="">matchDefault</span><span class=""> { </span><span class="">nil</span><span class=""> } </span>// Cant type call to fatalError as no return, hence nil and type Int! (note !)</span></div></blockquote><font class="" style="background-color: rgba(255, 255, 255, 0);"><div id="AppleMailSignature"><font class="" style="background-color: rgba(255, 255, 255, 0);"><br></font></div>Note runtime check for default rather than static check via compiler, not as good but not a big deal most of the time. The vast majority of languages don't do a compiler check on `switch`.</font></div><div id="AppleMailSignature"><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class="">Similarly the `?:` statement can be replaced:<br class=""><br class=""></font><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">// Replacement for `?:` operator</span></div><div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class="">struct</span> IfFalse<R> {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class=""> </span>private</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">let</span> result: <span class="">R</span>?</span></div><p class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"> </span></p><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">func</span> ifFalse(<span class="">@noescape</span> falseResult: () <span class="">throws</span> -> R) <span class="">rethrows</span> -> <span class="">R</span> {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">switch</span> <span class="">self</span>.<span class="">result</span> {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">case</span> .None:</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">return</span> <span class="">try</span> falseResult()</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">case</span> .Some(<span class="">let</span> value):</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">return</span> value</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">}</span></div><div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">extension<span class=""> </span><span class="">Bool</span><span class=""> {</span></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">func</span> ifTrue<R>(<span class="">@noescape</span> trueResult: () <span class="">throws</span> -> R) <span class="">rethrows</span> -> <span class="">IfFalse</span><<span class="">R</span>> {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">switch</span> <span class="">self</span> {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">case</span> <span class="">true</span>:</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">return</span> <span class="">IfFalse</span>(result: <span class="">try</span> trueResult())</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">case</span> <span class="">false</span>:</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">return</span> <span class="">IfFalse</span>(result: <span class="">nil</span>)</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">}</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">// Demo</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class="">let</span><span class=""> sB = </span><span class="">true</span><span class="">.</span><span class="">ifTrue</span><span class="">{</span><span class="">"True"</span><span class="">}.</span><span class="">ifFalse</span><span class="">{</span><span class="">"False"</span><span class="">} </span>// "True" - for some reason needs {} and not () thinks () form throws</span></div></blockquote><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font><div class="" style="margin: 0px; line-height: normal;"><font class="" style="background-color: rgba(255, 255, 255, 0);">Whilst the `??` operator is already a library function it is difficult to see in an expression, it gets buried, and is inconsistent in style because it is a non-mathematical operator and a symbol rather than a keyword or keyword followed by a symbol. The space either side of the `??` operator also makes it look like both arguments are of equal importance, whereas it is the left hand side that is important and the right hand side is just a catch.</font></div><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">// Replacement for `??` operator</span></div><div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">extension<span class=""> </span><span class="">Optional</span><span class=""> {</span></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">func</span> ifNil(<span class="">@noescape</span> nilResult: () <span class="">throws</span> -> Wrapped) <span class="">rethrows</span> -> <span class="">Wrapped</span> {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">switch</span> <span class="">self</span> {</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">case</span> .None:</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">return</span> <span class="">try</span> nilResult()</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">case</span> .Some(<span class="">let</span> value):</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> <span class="">return</span> value</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">}</span></div><div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">// Demo</span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class="">let</span> o: <span class="">String</span>? = <span class="">nil</span></span></div><div class="" style="margin: 0px; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"><span class="">let</span><span class=""> sO = </span><span class="">o</span><span class="">.</span><span class="">ifNil</span><span class="">{</span><span class="">"Nil"</span><span class="">} </span>// "Nil" - for some reason needs {} and not () thinks () form throws</span></div></blockquote><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font><span style="-webkit-text-size-adjust: auto;"></span><br>Sent from my iPad</div><div><br>On 29 Dec 2015, at 4:00 AM, Thorsten Seitz via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br><br></div><blockquote type="cite"><div><span>No exhaustiveness checking is a serious deficiency :-(</span><br><span></span><br><span>-Thorsten</span><br><span></span><br><blockquote type="cite"><span>Am 17.12.2015 um 08:09 schrieb Brent Royal-Gordon via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>>:</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Actually, this *almost* does what you want. No @autoclosure for the values and no exhaustiveness checking, but otherwise...</span><br></blockquote><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>