This proposal seems well-reasoned, but like Nevin I worry about the interactions between type narrowing, reference types or capture of mutable values, and concurrency or async. How will these things play together?<br><br><div class="gmail_quote"><div dir="ltr">On Thu, Nov 3, 2016 at 14:23 Nevin Brackett-Rozinsky via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg">This looks like a lot of complexity for very little gain.<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Aside from any implementation concerns, this proposal substantially increases the cognitive load on developers. To figure out what a piece of code means, someone reading it will have to mentally keep track of a “type stack” for every variable. That is the opposite of “clarity at the point of use”.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">For the motivating examples, there is already a much cleaner solution:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><font face="monospace, monospace" class="gmail_msg">(foo as? B)?.someMethodSpecificToB()</font><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Even in the case where foo gets passed as an argument to a function that takes a B, so optional chaining is not available, we are still okay. If foo is an instance of a struct, then passing it to a function won’t change its value so we can write:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><font face="monospace, monospace" class="gmail_msg">if let newFoo = foo as? B {</font></div><div class="gmail_msg"><font face="monospace, monospace" class="gmail_msg"> funcThatTakesB(newFoo)</font></div><div class="gmail_msg"><font face="monospace, monospace" class="gmail_msg">}</font></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">And if foo is an instance of a class, then the same thing *still* works, because any changes the function makes to newFoo are also observed in foo since they reference the same object.</div><div class="gmail_msg"><br class="gmail_msg"></div><div style="text-align:center" class="gmail_msg">• • •</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">The proposal’s other example is actually a great illustration of why shadowing is undesirable. After all, simply binding to a different name solves the so-called problem, *and* lets us bind to a constant:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><font face="monospace, monospace" class="gmail_msg">var foo: A? = A()</font></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><font face="monospace, monospace" class="gmail_msg">if let newFoo = foo {<br class="gmail_msg"></font></div><div class="gmail_msg"><font face="monospace, monospace" class="gmail_msg"> newFoo.someMethod()</font></div><div class="gmail_msg"><font face="monospace, monospace" class="gmail_msg"> foo!.someMutatingMethod() // Works now!</font></div><div class="gmail_msg"><font face="monospace, monospace" class="gmail_msg">}</font></div></div></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Full disclosure: both this and the original example have a *deeper* problem, which is that they are not thread-safe. If foo is modified between the conditional binding and the force-unwrap, the force-unwrap could fail. Sure, that can’t happen when foo is a local variable like this, but if it were a property of a class then it could.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Moreover, the proposed “solution” has the same concurrency failure, but hides it even worse because the force-unwrap operator doesn’t even appear in the code:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><font face="monospace, monospace" class="gmail_msg">var foo:A? = A()</font></div><div class="gmail_msg"><font face="monospace, monospace" class="gmail_msg">if foo != nil {</font></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><font face="monospace, monospace" class="gmail_msg"> foo.someMethod() // Bad news!</font></div><div class="gmail_msg"><font face="monospace, monospace" class="gmail_msg"> foo.someMutatingMethod() // Bad news!</font></div><div class="gmail_msg"><font face="monospace, monospace" class="gmail_msg">}</font></div></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">In summary, I do not see sufficient motivation for this proposal. The motivation which I do see appears superfluous. The problem being described already has an elegant solution in Swift. And the proposed changes introduce an exceptionally taxing cognitive burden on developers just to figure out what the type of a variable is on any given line of code.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Plus, in the face of concurrency, such implicit type-narrowing has the potential to hide serious issues.</div></div><div dir="ltr" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Nevin</div><div class="gmail_msg"><br class="gmail_msg"></div></div><div class="gmail_extra gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg">On Thu, Nov 3, 2016 at 1:04 PM, Haravikk via swift-evolution <span dir="ltr" class="gmail_msg"><<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br class="gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg">To avoid hijacking the guard let x = x thread entirely I've decided to try to write up a proposal on type narrowing in Swift.<div class="gmail_msg">Please give your feedback on the functionality proposed, as well as the clarity of the proposal/examples themselves; I've tried to keep it straightforward, but I do tend towards being overly verbose, I've always tried to have the examples build upon one another to show how it all stacks up.<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><h1 style="box-sizing:border-box;margin-right:0px;margin-bottom:16px;margin-left:0px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255);margin-top:0px!important" class="gmail_msg">Type Narrowing</h1><ul style="box-sizing:border-box;padding-left:2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg"><li style="box-sizing:border-box" class="gmail_msg">Proposal: <a href="https://github.com/Haravikk/swift-evolution/blob/master/proposals/NNNN-type-narrowing.md" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none" class="gmail_msg" target="_blank">SE-NNNN</a></li><li style="box-sizing:border-box;margin-top:0.25em" class="gmail_msg">Author: <a href="https://github.com/haravikk" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none" class="gmail_msg" target="_blank">Haravikk</a></li><li style="box-sizing:border-box;margin-top:0.25em" class="gmail_msg">Status: <span style="box-sizing:border-box;font-weight:600" class="gmail_msg">Awaiting review</span></li><li style="box-sizing:border-box;margin-top:0.25em" class="gmail_msg">Review manager: TBD</li></ul><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class="gmail_msg"><a id="m_1274740452557508557m_-7271769211814874654user-content-introduction" class="m_1274740452557508557m_-7271769211814874654anchor gmail_msg" href="https://github.com/Haravikk/swift-evolution/tree/master/proposals#introduction" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u></a>Introduction</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">This proposal is to introduce type-narrowing to Swift, enabling the type-checker to automatically infer a narrower type from context such as conditionals.</p><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">Swift-evolution thread: <a href="http://news.gmane.org/gmane.comp.lang.swift.evolution" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none" class="gmail_msg" target="_blank">Discussion thread topic for that proposal</a></p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class="gmail_msg"><a id="m_1274740452557508557m_-7271769211814874654user-content-motivation" class="m_1274740452557508557m_-7271769211814874654anchor gmail_msg" href="https://github.com/Haravikk/swift-evolution/tree/master/proposals#motivation" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u></a>Motivation</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">Currently in Swift there are various pieces of boilerplate required in order to manually narrow types. The most obvious is in the case of polymorphism:</p><pre style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)" class="gmail_msg"><code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal" class="gmail_msg">let foo:A = B() // B extends A
if foo is B {
(foo as B).someMethodSpecificToB()
}
</code></pre><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">But also in the case of unwrapping of optionals:</p><pre style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)" class="gmail_msg"><code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal" class="gmail_msg">var foo:A? = A()
if var foo = foo { // foo is now unwrapped and shadowed
foo.someMethod()
foo!.someMutatingMethod() // Can't be done
}
</code></pre><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class="gmail_msg"><a id="m_1274740452557508557m_-7271769211814874654user-content-proposed-solution" class="m_1274740452557508557m_-7271769211814874654anchor gmail_msg" href="https://github.com/Haravikk/swift-evolution/tree/master/proposals#proposed-solution" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u></a>Proposed solution</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">The proposed solution to the boiler-plate is to introduce type-narrowing, essentially a finer grained knowledge of type based upon context. Thus as any contextual clue indicating a more or less specific type are encountered, the type of the variable will reflect this from that point onwards.</p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class="gmail_msg"><a id="m_1274740452557508557m_-7271769211814874654user-content-detailed-design" class="m_1274740452557508557m_-7271769211814874654anchor gmail_msg" href="https://github.com/Haravikk/swift-evolution/tree/master/proposals#detailed-design" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u></a>Detailed design</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">The concept of type-narrowing would essentially treat all variables as having not just a single type, but instead as having a stack of increasingly specific (narrow) types.</p><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">Whenever a contextual clue such as a conditional is encountered, the type checker will infer whether this narrows the type, and add the new narrow type to the stack from that point onwards. Whenever the type widens again narrower types are popped from the stack.</p><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">Here are the above examples re-written to take advantage of type-narrowing:</p><pre style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)" class="gmail_msg"><code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal" class="gmail_msg">let foo:A = B() // B extends A
if foo is B { // B is added to foo's type stack
foo.someMethodSpecificToB()
}
// B is popped from foo's type stack
</code></pre><pre style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)" class="gmail_msg"><code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal" class="gmail_msg">var foo:A? = A()
if foo != nil { // Optional<A>.some is added to foo's type stack
foo.someMethod()
foo.someMutatingMethod() // Can modify mutable original
}
// Optional<A>.some is popped from foo's type stack
</code></pre><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class="gmail_msg"><a id="m_1274740452557508557m_-7271769211814874654user-content-enum-types" class="m_1274740452557508557m_-7271769211814874654anchor gmail_msg" href="https://github.com/Haravikk/swift-evolution/tree/master/proposals#enum-types" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u></a>Enum Types</h3><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">As seen in the simple optional example, to implement optional support each <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">case</code> in an <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">enum</code> is considered be a unique sub-type of the enum itself, thus allowing narrowing to <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">nil</code> (<code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">.none</code>) and non-<code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">nil</code> (<code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">.some</code>) types.</p><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">This behaviour actually enables some other useful behaviours, specifically, if a value is known to be either <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">nil</code> or non-<code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">nil</code> then the need to unwrap or force unwrap the value can be eliminated entirely, with the compiler able to produce errors if these are used incorrectly, for example:</p><pre style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)" class="gmail_msg"><code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal" class="gmail_msg">var foo:A? = A()
foo.someMethod() // A is non-nil, no operators required!
foo = nil
foo!.someMethod() // Error: foo is always nil at this point
</code></pre><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">However, unwrapping of the value is only possible if the case contains either no value at all, or contains a single value able to satisfy the variable's original type requirements. In other words, the value stored in <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">Optional<A>.some</code> satisfies the type requirements of <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">var foo:A?</code>, thus it is implicitly unwrapped for use. For general enums this likely means no cases are implicitly unwrapped unless using a type of <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">Any</code>.</p><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class="gmail_msg"><a id="m_1274740452557508557m_-7271769211814874654user-content-type-widening" class="m_1274740452557508557m_-7271769211814874654anchor gmail_msg" href="https://github.com/Haravikk/swift-evolution/tree/master/proposals#type-widening" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u></a>Type Widening</h3><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">In some cases a type may be narrowed, only to be used in a way that makes no sense for the narrowed type. In cases such as these the operation is tested against each type in the stack to determine whether the type must instead be widened. If a widened type is found it is selected (with re-narrowing where possible) otherwise an error is produced as normal.</p><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">For example:</p><pre style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)" class="gmail_msg"><code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal" class="gmail_msg">let foo:A? = A()
if (foo != nil) { // Type of foo is Optional<A>.some
foo.someMethod()
foo = nil // Type of foo is widened to Optional<A>, then re-narrowed to Optional<A>.none
} // Type of foo is Optional<A>.none
foo.someMethod() // Error: foo is always nil at this point
</code></pre><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class="gmail_msg"><a id="m_1274740452557508557m_-7271769211814874654user-content-multiple-conditions-and-branching" class="m_1274740452557508557m_-7271769211814874654anchor gmail_msg" href="https://github.com/Haravikk/swift-evolution/tree/master/proposals#multiple-conditions-and-branching" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u></a>Multiple Conditions and Branching</h3><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">When dealing with complex conditionals or branches, all paths must agree on a common type for narrowing to occur. For example:</p><pre style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)" class="gmail_msg"><code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal" class="gmail_msg">let foo:A? = B() // B extends A
let bar:C = C() // C extends B
if (foo != nil) || (foo == bar) { // Optional<A>.some is added to foo's type stack
if foo is B { // Optional<B>.some is added to foo's type stack
foo.someMethodSpecificToB()
} // Optional<B>.some is popped from foo's type stack
foo = nil // Type of foo is re-narrowed as Optional<A>.none
} // Type of foo is Optional<A>.none in all branches
foo.someMethod() // Error: foo is always nil at this point
</code></pre><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">Here we can see that the extra condition <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">(foo == bar)</code> does not prevent type-narrowing, as the variable <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">bar</code> cannot be <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">nil</code> so both conditions require a type of <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">Optional<A>.some</code> as a minimum.</p><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">In this example <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">foo</code> is also <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">nil</code> at the end of both branches, thus its type can remain narrowed past this point.</p><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class="gmail_msg"><a id="m_1274740452557508557m_-7271769211814874654user-content-context-triggers" class="m_1274740452557508557m_-7271769211814874654anchor gmail_msg" href="https://github.com/Haravikk/swift-evolution/tree/master/proposals#context-triggers" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u></a>Context Triggers</h3><table style="box-sizing:border-box;border-spacing:0px;border-collapse:collapse;margin-top:0px;margin-bottom:16px;display:block;width:888px;overflow:auto;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg"><thead style="box-sizing:border-box" class="gmail_msg"><tr style="box-sizing:border-box;border-top-width:1px;border-top-style:solid;border-top-color:rgb(204,204,204)" class="gmail_msg"><th style="box-sizing:border-box;padding:6px 13px;border:1px solid rgb(221,221,221)" class="gmail_msg">Trigger</th><th style="box-sizing:border-box;padding:6px 13px;border:1px solid rgb(221,221,221)" class="gmail_msg">Impact</th></tr></thead><tbody style="box-sizing:border-box" class="gmail_msg"><tr style="box-sizing:border-box;border-top-width:1px;border-top-style:solid;border-top-color:rgb(204,204,204)" class="gmail_msg"><td style="box-sizing:border-box;padding:6px 13px;border:1px solid rgb(221,221,221)" class="gmail_msg"><code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">as</code></td><td style="box-sizing:border-box;padding:6px 13px;border:1px solid rgb(221,221,221)" class="gmail_msg">Explicitly narrows a type with <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">as!</code> failing and <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">as?</code> narrowing to <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">Type?</code> instead when this is not possible.</td></tr><tr style="box-sizing:border-box;background-color:rgb(248,248,248);border-top-width:1px;border-top-style:solid;border-top-color:rgb(204,204,204)" class="gmail_msg"><td style="box-sizing:border-box;padding:6px 13px;border:1px solid rgb(221,221,221)" class="gmail_msg"><code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">is</code></td><td style="box-sizing:border-box;padding:6px 13px;border:1px solid rgb(221,221,221)" class="gmail_msg">Anywhere a type is tested will allow the type-checker to infer the new type if there was a match (and other conditions agree).</td></tr><tr style="box-sizing:border-box;border-top-width:1px;border-top-style:solid;border-top-color:rgb(204,204,204)" class="gmail_msg"><td style="box-sizing:border-box;padding:6px 13px;border:1px solid rgb(221,221,221)" class="gmail_msg"><code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">case</code></td><td style="box-sizing:border-box;padding:6px 13px;border:1px solid rgb(221,221,221)" class="gmail_msg">Any form of exhaustive test on an enum type allows it to be narrowed either to that case or the opposite, e.g- <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">foo != nil</code> eliminates <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">.none</code>, leaving only <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">.some</code> as the type, which can then be implicitly unwrapped (see Enum Types above).</td></tr><tr style="box-sizing:border-box;background-color:rgb(248,248,248);border-top-width:1px;border-top-style:solid;border-top-color:rgb(204,204,204)" class="gmail_msg"><td style="box-sizing:border-box;padding:6px 13px;border:1px solid rgb(221,221,221)" class="gmail_msg"><code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">=</code></td><td style="box-sizing:border-box;padding:6px 13px;border:1px solid rgb(221,221,221)" class="gmail_msg">Assigning a value to a type will either narrow it if the new value is a sub-type, or will trigger widening to find a new common type, before attempting to re-narrow from there.</td></tr></tbody></table><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">There may be other triggers that should be considered.</p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class="gmail_msg"><a id="m_1274740452557508557m_-7271769211814874654user-content-impact-on-existing-code" class="m_1274740452557508557m_-7271769211814874654anchor gmail_msg" href="https://github.com/Haravikk/swift-evolution/tree/master/proposals#impact-on-existing-code" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u></a>Impact on existing code</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="gmail_msg">Although this change is technically additive, it will impact any code in which there are currently errors that type-narrowing would have detected; for example, attempting to manipulate a predictably <code style="box-sizing:border-box;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="gmail_msg">nil</code> value.</p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class="gmail_msg"><a id="m_1274740452557508557m_-7271769211814874654user-content-alternatives-considered" class="m_1274740452557508557m_-7271769211814874654anchor gmail_msg" href="https://github.com/Haravikk/swift-evolution/tree/master/proposals#alternatives-considered" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u><u class="gmail_msg"></u></a>Alternatives considered</h2><div style="box-sizing:border-box;margin-top:0px;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255);margin-bottom:0px!important" class="gmail_msg">One of the main advantages of type-narrowing is that it functions as an alternative to other features. This includes alternative syntax for shadowing/unwrapping of optionals, in which case type-narrowing allows an optional to be implicitly unwrapped simply by testing it, and without the need to introduce any new syntax.</div></div></div></div><br class="gmail_msg">_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
<br class="gmail_msg"></blockquote></div><br class="gmail_msg"></div>
_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div>