<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On 17 Dec 2015, at 12:25, Brent Royal-Gordon via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Occasionally, Optional&lt;Void&gt; comes up in Swift. This particularly happens with optional chaining (and its socially awkward twin `Optional.flatMap(_:)`), but I occasionally see it come up in other places, particularly where you’re using a Result-ish type. Wherever it does come up, it seems to have the same semantic meaning as Bool, with `nil` meaning `false` and `()` meaning `true`.<br class=""></div></div></blockquote><div><br class=""></div><div>It's true that&nbsp;<span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Optional</span><span style="font-family: Menlo; font-size: 11px;" class="">&lt;</span><span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Void</span><span style="font-family: Menlo; font-size: 11px;" class="">&gt;</span>&nbsp;corresponds to&nbsp;<span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Bool</span>, but those aren't the only isomorphic types to each other. There's also&nbsp;<span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Bit</span>, and I could list a lot of other more domain-specific&nbsp;<span style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;" class="">enum</span>s that just happen to have two cases with no associated data.</div><div><br class=""></div><div>I think it would be very confusing to people when&nbsp;<span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Optional</span><span style="font-family: Menlo; font-size: 11px;" class="">&lt;</span><span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Void</span><span style="font-family: Menlo; font-size: 11px;" class="">&gt;.</span><span style="font-family: Menlo; font-size: 11px; color: rgb(61, 29, 129);" class="">Some</span><span style="font-family: Menlo; font-size: 11px;" class="">()</span>&nbsp;were suddenly a common thing. (Possibly related to this is that&nbsp;<span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Bool</span>&nbsp;is a&nbsp;<span style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;" class="">struct</span>&nbsp;and not an&nbsp;<span style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;" class="">enum</span>&nbsp;in Swift.)</div><br class=""><blockquote type="cite" class=""><div class=""><div class="">Does it make sense to somehow unify them? Perhaps turn Bool into a typealias for Optional&lt;Void&gt; and move all of its conformances into (not yet supported) conditional conformances on Optional?<br class=""></div></div></blockquote></div><br class=""><div class="">The one thing I'd suggest instead is if&nbsp;<span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Void</span>&nbsp;were made&nbsp;<span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Equatable</span>. In that case, you'd convert from&nbsp;<span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Optional</span><span style="font-family: Menlo; font-size: 11px;" class="">&lt;</span><span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Void</span><span style="font-family: Menlo; font-size: 11px;" class="">&gt;</span>&nbsp;to&nbsp;<span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Bool</span>&nbsp;by simply comparing against&nbsp;<span style="font-family: Menlo; font-size: 11px;" class="">()</span>:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> optional: ()? = ...</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> bool = <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">optional</span> == ()</div></div></blockquote><div class=""><br class=""></div><div class="">And before someone says it's impossible because tuples aren't nominal types in Swift (yet), this all could be emulated (for now) by overloading&nbsp;<span style="font-family: Menlo; font-size: 11px;" class="">==</span>&nbsp;and&nbsp;<span style="font-family: Menlo; font-size: 11px;" class="">!=</span>:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="color: rgb(187, 44, 162);" class="">@warn_unused_result</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> ==(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span>: (), <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span>: ()) -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span> { <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">true</span> }</div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal;" class=""><span style="color: rgb(187, 44, 162);" class="">@warn_unused_result</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> !=(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span>: (), <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span>: ()) -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span> { <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">false</span> }</div><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><div style="margin: 0px; line-height: normal; color: rgb(187, 44, 162);" class="">@warn_unused_result</div></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> ==(a: ()?, b: ()?) -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span> {</div><div style="margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">switch</span> (a, b) {</div><div style="margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">case</span> (()?, ()?), (<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">nil</span>, <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">nil</span>): <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">true</span></div><div style="margin: 0px; line-height: normal; color: rgb(187, 44, 162);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&nbsp; &nbsp; </span>default<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">: </span>return<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span>false</div><div style="margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; line-height: normal;" class="">}</div><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><div style="margin: 0px; line-height: normal; color: rgb(187, 44, 162);" class="">@warn_unused_result</div></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> !=(a: ()?, b: ()?) -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span> {</div><div style="margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> !(a <span style="font-variant-ligatures: no-common-ligatures; color: #31595d" class="">==</span> b)</div><div style="margin: 0px; line-height: normal;" class="">}</div></div></blockquote><div class=""><br class=""></div><div class="">Another question though is whether <i class="">not</i>&nbsp;defining&nbsp;<span style="font-family: Menlo; font-size: 11px;" class="">() </span><span style="font-family: Menlo; font-size: 11px; color: rgb(49, 89, 93);" class="">==</span><span style="font-family: Menlo; font-size: 11px;" class=""> ()</span>&nbsp;also servers as a sanity check against making something stupid like comparing the result of a side-effectful function against&nbsp;<span style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;" class="">nil</span>&nbsp;by mistake. But it turns out the compiler is actually pretty clever against unintended&nbsp;<span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Void</span>&nbsp;or&nbsp;<span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Void?</span>:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">class</span> Missile {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&nbsp; &nbsp; </span>// Maybe it once returned `()?` or something.</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&nbsp; &nbsp; </span>//func launch() -&gt; ()? { return nil }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> launch() {}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> result = <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Missile</span>().<span style="font-variant-ligatures: no-common-ligatures; color: #31595d" class="">launch</span>()</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class="">//&nbsp; ^</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class="">// warning: constant 'result' inferred to have type '()', which may be unexpected</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class="">// note: add an explicit type annotation to silence this warning</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> explicit: ()? = <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">result</span> <span style="font-variant-ligatures: no-common-ligatures; color: #008400" class="">// no warning</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> bool = <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">result</span> != <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">nil</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class="">// &nbsp; &nbsp; &nbsp; &nbsp; ~~~~~~ ^</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class="">// error: value of type '()' can never be nil, comparison isn't allowed</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> optional = <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Optional</span>(<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">result</span>)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class="">//&nbsp; ^</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class="">// warning: constant 'optional' inferred to have type 'Optional&lt;()&gt;', which may be unexpected</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">if</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">optional</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #31595d" class="">==</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> () { </span>// No warning.</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">print</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(</span>"Missile launched, I'm afraid!"<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div></blockquote><div class=""><br class=""></div><div class="">— Pyry Jahkola</div><div class=""><br class=""></div></body></html>