<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><div class="">On Jun 29, 2016, at 8:47 AM, Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>&gt; wrote:</div><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class=""><br class="">On Jun 29, 2016, at 7:52 AM, David Sweeris via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div class="">Aside from confusing people, does it actually hurt anything? It's not too hard to imagine that someone might make a type conform to `Boolean` because, within their code, the semantics of "x || y” are clear and that reads better than "x.foo || y.foo".<br class=""><br class=""></div><div class="">I agree it feels out of place, though. What about renaming it to something like "CustomBooleanConvertible”?</div></div></blockquote><div class=""><br class=""></div>IIRC Optional conformed to this protocol early on and that conformance was removed. &nbsp;In practice the idea of a protocol for "truthiness" to which non-Boolean types conform caused more confusion than it provided value. &nbsp;It was a cool idea that just didn't work out so well.<div class=""><br class=""></div><div class="">IMO if it doesn't make sense for Optional to conform it is pretty unlikely it would make sense for other types to conform. &nbsp;It seems like a good idea to remove the protocol.<br class=""></div></div></div></blockquote></div><br class=""><div class="">What if you wanted to do something like this?</div><div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">class</span><span style="font-variant-ligatures: no-common-ligatures" class=""> RemoteBool : </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Boolean</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> url: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">URL</span></div><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&nbsp; &nbsp;&nbsp;</span><span style="color: rgb(187, 44, 162); font-variant-ligatures: no-common-ligatures;" class="">private</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);" class="">&nbsp;</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">var</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);" class=""> cachedValue: </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);" class="">? = </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">nil</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);" class=""> </span><span style="font-variant-ligatures: no-common-ligatures;" class="">// gets updated periodically in another thread or some other async method</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class="">(boolURL: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">URL</span><span style="font-variant-ligatures: no-common-ligatures" class="">) { </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">url</span><span style="font-variant-ligatures: no-common-ligatures" class=""> = boolURL; </span><span style="font-variant-ligatures: no-common-ligatures; color: #31595d" class="">sync_update</span><span style="font-variant-ligatures: no-common-ligatures" class="">() }</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> boolValue: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class=""> { </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">cachedValue</span><span style="font-variant-ligatures: no-common-ligatures" class=""> ?? </span><span style="font-variant-ligatures: no-common-ligatures; color: #31595d" class="">sync_update</span><span style="font-variant-ligatures: no-common-ligatures" class="">() }</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> sync_update() -&gt; </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {…</span><span style="font-variant-ligatures: no-common-ligatures" class="">}&nbsp;</span><span style="color: rgb(0, 132, 0); font-variant-ligatures: no-common-ligatures;" class="">// synchronously sets `cachedValue` and returns the newValue</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> async_update() {…}&nbsp;</span><span style="color: rgb(0, 132, 0);" class="">// asynchronously sets `cachedValue`</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div></div></div></div><div class="">Or experiment with how ternary logic interacts with boolean logic?</div><div class=""><div style="margin: 0px; line-height: normal;" class=""><div style="margin: 0px; line-height: normal;" class=""><div style="font-family: Menlo; margin: 0px; line-height: normal;" class=""><div style="margin: 0px; line-height: normal; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> Ternary : </span><span style="font-variant-ligatures: no-common-ligatures" class="">Boolean</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">, </span><span style="font-variant-ligatures: no-common-ligatures" class="">BooleanLiteralConvertible</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">, </span><span style="font-variant-ligatures: no-common-ligatures" class="">NilLiteralConvertible</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> {</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">static</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp;forcedBoolValue<span style="font-variant-ligatures: no-common-ligatures;" class="">: </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> { </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">get</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> }</span></span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> ternValue: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class="">? { </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">get</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">set</span><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span><span style="font-variant-ligatures: no-common-ligatures" class="">: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class="">?)</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; line-height: normal; color: rgb(187, 44, 162);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">extension</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Ternary</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> {</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> boolValue: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class=""> { </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">ternValue</span><span style="font-variant-ligatures: no-common-ligatures" class=""> ?? </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures" class=""><span style="color: rgb(79, 129, 135);" class="">forcedBoolValue</span>&nbsp;}</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class="">(booleanLiteral value: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class="">) { </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class="">(value) }</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class="">(nilLiteral: ()) { </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">nil</span><span style="font-variant-ligatures: no-common-ligatures" class="">) }</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">struct</span><span style="font-variant-ligatures: no-common-ligatures" class=""> TendsTrue:&nbsp;</span><span style="font-variant-ligatures: no-common-ligatures" class=""><span style="color: rgb(79, 129, 135);" class="">Ternary</span>&nbsp;{</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">static</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp;forcedBoolValue&nbsp;= </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" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> ternValue: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class="">?</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span><span style="font-variant-ligatures: no-common-ligatures" class=""> value: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class="">?) { </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">ternValue</span><span style="font-variant-ligatures: no-common-ligatures" class=""> = value }</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">struct</span><span style="font-variant-ligatures: no-common-ligatures" class=""> TendsFalse:&nbsp;</span><span style="font-variant-ligatures: no-common-ligatures" class=""><span style="color: rgb(79, 129, 135);" class="">Ternary</span>&nbsp;{</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">static</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp;forcedBoolValue&nbsp;= </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">false</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> ternValue: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class="">?</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span><span style="font-variant-ligatures: no-common-ligatures" class=""> value: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class="">?) { </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">ternValue</span><span style="font-variant-ligatures: no-common-ligatures" class=""> = value }</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div></div><div class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">Yeah, sure, in either case you could go through and use extensions to add support for your custom type on an as-needed basis. Life would</span>&nbsp;be way easier, though, if the standard library was simply coded to an abstracted boolean protocol. Isn’t this kind of scenario that led to Swift having generics?</div><div class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><br class=""></span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">Renaming `Boolean` to something that doesn’t sort next to `Bool` removes the source of confusion. And while I <i class="">completely</i> agree that the standard library should be consistent it its use of abstraction protocols vs concrete types,&nbsp;</span>in this regard I think this proposal goes in the wrong direction (although, in my whatever-the-opposite-of-defense-is I’m a <i class="">huge</i> fan of having generic library code wherever possible, so maybe I’m biased).</div><div class=""><br class=""></div><div class="">Is there a downside to overloading any function which takes a Bool with a version that takes a “CustomBooleanConvertible”?</div><div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> foo(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> bar: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">) {} </span><span style="font-variant-ligatures: no-common-ligatures" class="">// pretend this exists in the standard library</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> foo &lt;T: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">CustomBooleanConvertible</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&gt; (</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> bar: </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">) { </span><span style="font-variant-ligatures: no-common-ligatures; color: #31595d" class="">foo</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(bar.</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">boolValue</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">) } </span><span style="font-variant-ligatures: no-common-ligatures" class="">// add this, and keep the concrete version as well, both to provide the actual implementation and to prevent the generic version from recursively calling itself</span></div></div><div class=""><br class=""></div><div class="">- Dave Sweeris</div></div></div></div></body></html>