<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=""><div class="">As pleasing as it sounds*), the idea of type narrowing breaks down badly if:</div><div class=""><br class=""></div><div class="">– the binding is implicit (without explicit extra syntax involved) and</div><div class="">– what is bound happens to be mutable.</div><div class=""><br class=""></div><div class="">An example being:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; <font color="#919191" class="">// <b class="">var</b> message: String?</font></font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; <b class="">if</b> message != <b class="">nil</b> { <font color="#919191" class="">// magic turns 'message' into a non-optional 'String' here</font></font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; handleMessage(message)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; message = <b class="">nil</b> <font color="#919191" class="">// 'String' is not 'ExpressibleByNilLiteral'</font></font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; }</font></div><div class=""><br class=""></div><div class="">What magic would we require to still allow access to the Optional interface of 'message' in that block? In other words, I'm afraid type narrowing for Swift's enums (including Optional) isn't quite as simple as that.</div><div class=""><br class=""></div><div class="">— Pyry</div><div class=""><br class=""></div><div class="">*) OTOH, I could see much benefit from being able to narrow down enums of all kinds, e.g. `<font face="Menlo" class="">Result&lt;T&gt;</font>` such that in the `<font face="Menlo" class=""><b class="">else</b></font>` branch of a failing `<font face="Menlo" class=""><b class="">guard case let</b> .success(value) = result</font>`, the `<font face="Menlo" class="">error</font>` value of `<font face="Menlo" class=""><b class="">case</b> failure(error)</font>` were guaranteed by the compiler to be readily available, something like:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; <b class="">enum</b> Result&lt;T&gt; { <b class="">case</b> success(T); <b class="">case</b> failure(Error) }</font></div><div class=""><font face="Menlo" color="#919191" class="">&nbsp; &nbsp; // ...</font></div><div class=""><font face="Menlo" color="#919191" class="">&nbsp; &nbsp; // <b class="">let</b> result: Result&lt;String&gt;</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; <b class="">guard case let</b> .success(string) = result</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; <b class="">else case let</b> .failure(error) = result {</font></div><div class=""><font face="Menlo" color="#919191" class="">&nbsp; &nbsp; &nbsp; // ^</font></div><div class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color: rgb(145, 145, 145); font-family: Menlo;" class="">// Guaranteed to succeed because 'result' was proven to be of '</span><span style="color: rgb(145, 145, 145); font-family: Menlo;" class=""><b class="">case</b></span><span style="color: rgb(145, 145, 145); font-family: Menlo;" class="">&nbsp;</span><span style="color: rgb(145, 145, 145); font-family: Menlo;" class="">failure(Error)'</span></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; <b class="">throw</b> error</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; print(string)</font></div><br class=""><div><blockquote type="cite" class=""><div class="">On 3 Nov 2016, at 6.37, Hooman Mehr 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=""><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=""><div dir="auto" 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 Nov 2, 2016, at 2:02 PM, Matthew Johnson via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><div class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">On Nov 2, 2016, at 3:47 PM, Sean Heber via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class="">For what it’s worth, I concur. I think type narrowing makes it feel more like the language is actually doing some work *for* me rather than me having to babysit the language with some new syntax or keyword.<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">I’ve been staying out of the discussion because it doesn’t seem particularly relevant to Swift 4 phase 1, but +1. &nbsp;Type narrowing is by far the most general and scalable solution which could be applied in other ways in the future.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div class=""><br class=""></div><div class="">Same as me, I was staying out as well.&nbsp;</div><div class="">+1 for type narrowing instead of the original proposal. Thank you Haravikk for bringing this up.</div><br class=""><blockquote type="cite" class=""><div class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class=""><br class="">l8r<br class="">Sean<br class=""><br class=""><blockquote type="cite" class="">On Nov 2, 2016, at 3:25 PM, Haravikk via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class="">I still think that type narrowing is the right way to handle this like so:<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>if x != nil {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>// x is definitely not nil inside this block (implicitly unwrapped)<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>} // x remains optional outside of it<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>if (x != nil) || (x == y) {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>// if y's type is non-optional, then x is definitely not nil inside this block also<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>// i.e- if all conditions narrow to the same result, the type is narrowed inside the block<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>if x is Foo {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>x.someMethodSpecificToFoo()<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}<br class=""><br class="">Personally I'm very much against the use of shadowing in the first place, and never use it myself. I tend to precede unwrapped value with "this" like so:<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>if let thisFoo = foo {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>// Do something with thisFoo<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}<br class=""><br class="">I know it's maybe down to personal preference but I'd prefer to discourage shadowing entirely, and focus on type-narrowing, as it's a much more natural, and more generally useful, way to handle this "problem", as it doesn't actually require a specific syntax at all; if your condition narrows the type, then you can use the variable as whatever it is known to be.</blockquote></blockquote></div></blockquote></div></div></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="">

<br class=""></body></html>