<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 15 Nov 2016, at 07:19, Jean-Daniel &lt;<a href="mailto:dev@xenonium.com" class="">dev@xenonium.com</a>&gt; wrote:</div><div class=""><div 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=""><blockquote type="cite" class=""><div class="">Le 14 nov. 2016 à 10:10, Haravikk &lt;<a href="mailto:swift-evolution@haravikk.me" class="">swift-evolution@haravikk.me</a>&gt; a écrit :</div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><blockquote type="cite" class=""><div class="">On 13 Nov 2016, at 16:16, Jean-Daniel via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><div class=""><div class="" 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;"><blockquote type="cite" class=""><div class="">Le 13 nov. 2016 à 03:37, Dennis Lysenko via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; a écrit :</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">That's a good point in Jay's example and from what I can tell a good way to address it, Haravikk.&nbsp;<div class=""><br class=""></div><div class="">I've done some work in a language that only provides type narrowing for immutable types (that'd be Kotlin as I've mentioned before) and whenever I've used it it feels like the only thing it's really been missing is the "if let" construct allowing you to bind and unwrap mutable values, which leads me to think that synergistically, in Swift, this would be fantastic. The main benefit probably is that it would allow code to read much better.</div></div></div></blockquote><div class=""><br class=""></div>IMHO, the Kotlin solution is flaw. The fact that type narrowing does not works for var and that there is no simple way to unwrap optional just force the developer either to introduce local variable, or to use the force unwrap operator.</div><div class="" 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;">Moreover, introducing a unwrap syntax (if let) like in swift would just result in having 2 different and inconsistent way to do the same thing.</div></div></blockquote><br class=""></div><div class="">I'll have to take a closer look at how Kotlin does this when I get a chance, but how would this affect the two proposals as they currently stand?</div><div class=""><br class=""></div><div class=""><a href="https://github.com/Haravikk/swift-evolution/blob/master/proposals/NNNN-type-narrowing.md" class="">https://github.com/Haravikk/swift-evolution/blob/master/proposals/NNNN-type-narrowing.md</a></div><div class=""><a href="https://github.com/Haravikk/swift-evolution/blob/master/proposals/NNNN-optional-unwrapping.md" class="">https://github.com/Haravikk/swift-evolution/blob/master/proposals/NNNN-optional-unwrapping.md</a></div><div class=""><br class=""></div><div class="">These keep automatic narrowing of polymorphic types, but requires explicit narrow/unwrapping of optionals (because we can define methods/properties on Optional there's no other choice unfortunately); it would work for both mutable and immutable values, but mutable reference types require an extra step due to the potential for unsafe operations.</div><div class=""><br class=""></div><div class="">I think that's about as flexible as we're going to be able to get without introducing other difficulties.</div></div></div></blockquote></div><br class="" 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;"><div class="" 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;">While the proposals try to be less restrictive than Kotlin, I don’t like the way they handle concurrency.</div><div class="" 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;">All usage of the ‘!’ operator in swift guarantee a crash at the call site if something is wrong (try!, as!, optional!, …). In the proposals, the ‘!’ operator means that the app may crash at call site or may crash later.</div></div></blockquote></div><br class=""><div class="">The error should still be associated with the line that actually failed, the only difference here is that the type-checking or force-unwrapping is handled for you behind the scenes, as you've opted into it for that scope by forcing the unwrap/narrowing to occur. Put another way; when you force unwrap/narrow a reference type, it is treated like an implicitly unwrapped Optional or implicitly narrowed type, so is checked for correctness as necessary.</div><div class=""><br class=""></div><div class="">Since narrowing/unwrapping has (sort of) occurred, we can produce an error that better highlights the problem, e.g- "Force unwrapped reference was set to nil by another method or thread", as the unwrap/narrowing functionality ensures that you can't do it in the current scope without it being detected. The error that requires you to use force unwrapping/narrowing can likewise be more specific, e.g- "Reference type foo cannot be unwrapped/narrowed safely" (I suck at writing error messages btw), the idea being to encourage developers to consider why and decide for themselves whether it's better to force the unwrap/narrowing (because they're confident it will work) or to instead work with a copy and put it back later, use locking etc. etc.</div><div class=""><br class=""></div><div class="">The only other component is an attribute to indicate when a reference is safe; I'm favouring something like @concurrency(safe), but the difficulty is whether it's enough to just indicate this or if it also needs to be enforced somehow. I might use the attribute for example on a property I know will be used in a copy-on-write style, but is it feasible to enforce that, perhaps with some kind of behaviour similar to no-escape? It becomes tough to consider every possible case for something like that, and it'd probably need some other supporting features, like a @copy attribute for return types so we can account for methods methods that produce a new copy of an instance (e.g- if your return type has the @copy attribute then it can't return self). It's probably more of a separate proposal though for how we'll handle concurrency and reference types natively.</div><div class=""><br class=""></div><div class="">Little bit off track there, but the short version is; forcing the unwrap/narrowing doesn't make your code any more or less safe for references, it just removes the need for force-unwrap or type check everything manually.</div></body></html>