<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Amir,<div class=""><br class=""></div><div class="">I confess that I’m not really understanding what you don’t like about the operator ??.</div><div class=""><br class=""></div><div class="">Personally I find it very clear and read it as „or else“. The only worthwhile alternative to ?? would be a method on Optional called `orElse()` like e.g. Java has which expresses the notion quite clearly but with a bit more visual clutter than ??:</div><div class=""><br class=""></div><div class="">(x?.isEmpty).orElse(false)<span class="Apple-tab-span" style="white-space:pre">                </span>// same as x?.isEmpty ?? false</div><div class=""><br class=""></div><div class="">Besides having less visual clutter I see another advantage to the operator ??: when I want to do something similar on the level of functions of type T -> U? instead of values of type U? I could define an operator ??? which works similar to ??</div><div class="">This would not be possible with a method orElse() because AFAIK it is not possible to add methods to functions.</div><div class="">(This idea relates to the thread about having first class partial functions).</div><div class=""><br class=""></div><div class="">Example:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(133, 153, 1);" class="">infix<span style="font-variant-ligatures: no-common-ligatures; color: #839496" class=""> </span>operator<span style="font-variant-ligatures: no-common-ligatures; color: #839496" class=""> ??? {}</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150); min-height: 15px;" class=""><br class=""></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">func</span> ???<T,U>(lhs: <span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">T</span> -> <span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">U</span>?, rhs: <span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">T</span> -> <span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">U</span>?) -> <span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">T</span> -> <span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">U</span>? {</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">func</span> result(x: <span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">T</span>) -> <span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">U</span>? {</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">if</span> <span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">let</span> res = lhs(x) {</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">return</span> res</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""> }</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">else</span> {</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">return</span> rhs(x)</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""> }</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""> }</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(133, 153, 1);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #839496" class=""> </span>return<span style="font-variant-ligatures: no-common-ligatures; color: #839496" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #6c71c4" class="">result</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class="">}</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150); min-height: 15px;" class=""><br class=""></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">func</span> isEven(x: <span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">Int</span>) -> <span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">String</span>? {</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">switch</span> x {</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">case</span> x <span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">where</span> x % <span style="font-variant-ligatures: no-common-ligatures; color: #29a198" class="">2</span> == <span style="font-variant-ligatures: no-common-ligatures; color: #29a198" class="">0</span>: <span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #29a198" class="">"</span>\<span style="font-variant-ligatures: no-common-ligatures; color: #29a198" class="">(</span>x<span style="font-variant-ligatures: no-common-ligatures; color: #29a198" class="">) is even"</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(133, 153, 1);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #839496" class=""> </span>default<span style="font-variant-ligatures: no-common-ligatures; color: #839496" class="">: </span>return<span style="font-variant-ligatures: no-common-ligatures; color: #839496" class=""> </span>nil</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""> }</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class="">}</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150); min-height: 15px;" class=""><br class=""></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">func</span> isOdd(x: <span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">Int</span>) -> <span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">String</span>? {</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">switch</span> x {</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">case</span> x <span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">where</span> x % <span style="font-variant-ligatures: no-common-ligatures; color: #29a198" class="">2</span> == <span style="font-variant-ligatures: no-common-ligatures; color: #29a198" class="">1</span>: <span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #29a198" class="">"</span>\<span style="font-variant-ligatures: no-common-ligatures; color: #29a198" class="">(</span>x<span style="font-variant-ligatures: no-common-ligatures; color: #29a198" class="">) is odd"</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(133, 153, 1);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #839496" class=""> </span>default<span style="font-variant-ligatures: no-common-ligatures; color: #839496" class="">: </span>return<span style="font-variant-ligatures: no-common-ligatures; color: #839496" class=""> </span>nil</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""> }</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class="">}</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150); min-height: 15px;" class=""><br class=""></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(108, 113, 196);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">let</span><span style="font-variant-ligatures: no-common-ligatures; color: #839496" class=""> f = </span>isEven<span style="font-variant-ligatures: no-common-ligatures; color: #839496" class=""> </span>???<span style="font-variant-ligatures: no-common-ligatures; color: #839496" class=""> </span>isOdd</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150); min-height: 15px;" class=""><br class=""></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(88, 110, 117);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #d33682" class="">f</span><span style="font-variant-ligatures: no-common-ligatures; color: #839496" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #29a198" class="">3</span><span style="font-variant-ligatures: no-common-ligatures; color: #839496" class="">) </span>// => "3 is odd"</div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">-Thorsten</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div><blockquote type="cite" class=""><div class="">Am 29.01.2016 um 17:58 schrieb Amir Michail via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>>:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jan 29, 2016, at 9:25 AM, Ross O'Brien <<a href="mailto:narrativium+swift@gmail.com" class="">narrativium+swift@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">What about it?<div class=""><br class=""></div><div class="">"x ?? false" is simple. If x isn't nil, return x; if x is nil, return false.</div><div class="">"x?.isEmpty ?? false" again is already readable; if x isn't nil, return x.isEmpty; if x is nil, return false.</div><div class=""><br class=""></div><div class=""><div class="">"Bool(x?.isEmpty)" seems be suggesting that the Bool type has a failable initialiser "init?(_: Bool?)". If x is nil, x.isEmpty would be nil, so the resulting Bool would be nil, not false - this code returns a Bool?, which you already had.</div></div><div class=""><br class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">How about this:</div><div class=""><br class=""></div><div class="">if? !x?.isEmpty { … } // if? nil { … } = if false { … }</div><div class="">while? !x?.isEmpty { … }</div><div class="">etc.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">"??(false, x?.isEmpty)" ... uses an operator as an identifier, for a start. At best I'd try to interpret this like reduce - take a collection or variadic list of optionals, return the value of the first non-nil else return the "default". Except I'd still put the default at the end, because I can't think why it would be at the start.</div><div class=""><br class=""></div><div class="">So, if the given problem is taking the nil-coalescing and putting it up front, perhaps there should be a global generic function:</div><div class=""><br class=""></div><div class="">func firstNonOptional<T>(possibles:T?..., failsafe:T) -> T</div><div class="">{</div><div class=""> return possibles.reduce(nil, combine:{ $0 ?? $1 }) ?? failsafe</div><div class="">}</div><div class=""><br class=""></div><div class=""> <br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Fri, Jan 29, 2016 at 1:48 PM, Amir Michail via swift-evolution <span dir="ltr" class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jan 29, 2016, at 8:42 AM, Craig Cruden <<a href="mailto:ccruden@novafore.com" target="_blank" class="">ccruden@novafore.com</a>> wrote:</div><br class=""><div class=""><div style="word-wrap:break-word" class="">still much worse.<div class=""><br class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">What about: Bool(x?.isEmpty) // nil and false => false</div><div class=""><div class="h5"><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 2016-01-29, at 20:41:06, Amir Michail via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><br class=""><div class=""><div style="word-wrap:break-word" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jan 29, 2016, at 5:03 AM, Thorsten Seitz <<a href="mailto:tseitz42@icloud.com" target="_blank" class="">tseitz42@icloud.com</a>> wrote:</div><br class=""><div class=""><div class=""><div class="">I agree with Erica. The ?? operator is very readable IMO.<br class=""></div><div class=""><br class=""></div><div class="">Furthermore x?(false).isEmpty looks like it would evaluate false.isEmpty when x is nil which is certainly not what is intended.<br class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">What about this then: ??(false, x?.isEmpty)</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><div class="">In addition it would not be clear which default should be used in case of multiple optional chainings happening, i.e. what should be the result of person?(false).address?.(true).isEmpty<br class=""></div><div class=""><br class=""></div><div class="">-Thorsten</div><div class=""><br class=""></div><div class=""><br class="">Am 26. Januar 2016 um 03:29 schrieb Erica Sadun via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>>:<br class=""><br class=""><div class=""><blockquote type="cite" class=""><div class=""><div class=""><span class="">Not loving this. I'm quite happy with ??-coalescing and don't see<br class="">a compelling reason it needs to be "cleaner". I find your suggested<br class="">enhancement less readable. Looks like an optional chaining across <br class="">a function.<br class=""><br class="">-- E<br class=""><br class=""><blockquote type="cite" class="">On Jan 25, 2016, at 7:03 PM, Amir Michail via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</blockquote><blockquote type="cite" class=""><br class=""></blockquote><blockquote type="cite" class="">Examples:</blockquote><blockquote type="cite" class=""><br class=""></blockquote><blockquote type="cite" class="">* instead of x ?? false, you would have x?(false)</blockquote><blockquote type="cite" class="">* instead of x?.isEmpty ?? false, you would have x?(false).isEmpty</blockquote><blockquote type="cite" class=""><br class=""></blockquote><blockquote type="cite" class="">I think this change would result in cleaner looking code.</blockquote><blockquote type="cite" class=""><br class=""></blockquote><blockquote type="cite" class=""><br class=""></blockquote><blockquote type="cite" class="">_______________________________________________</blockquote><blockquote type="cite" class="">swift-evolution mailing list</blockquote><blockquote type="cite" class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""></blockquote><blockquote type="cite" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></blockquote><br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></span></div></div></blockquote></div></div></div></div></blockquote></div><br class=""></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div></div></blockquote></div></div></div><br class=""></div><br class="">_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
<br class=""></blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></div></body></html>