<div dir="ltr">On Mon, Oct 31, 2016 at 8:37 PM, Joe Groff via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Sorry for piling onto the bikeshed. We do already have a notation for testing that an Optional isn't nil, `x != nil`. We could theoretically bless `<decl ref> != nil` as a statement condition to also unwrap the referenced declaration in the scope guarded by the condition. (`<decl ref> is T` could similarly rebind a declaration as the cast type.)<br></blockquote><div><br></div><div>I think we'd have some weirdness. For instance:</div><div><br></div><div>```</div><div><div>guard x != nil || x == y else { break }</div><div>// oops, now x isn't unwrapped anymore because I added a condition<br></div></div><div>```</div><div><br></div><div>Also, it'd be unexpected for it to be blessed for guard but not if:</div><div><br></div><div>```</div><div>if x != nil {</div><div> // is x unwrapped here?</div><div> // if so, this would be source-breaking...</div><div> // if not, it would be surprisingly inconsistent</div><div>}</div><div>```</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
-Joe<br>
<div class="gmail-HOEnZb"><div class="gmail-h5"><br>
> On Oct 28, 2016, at 3:34 PM, Erica Sadun via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br>
><br>
><br>
>> On Oct 26, 2016, at 11:39 AM, Chris Lattner via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br>
>><br>
>><br>
>>> On Oct 26, 2016, at 10:23 AM, Joshua Alvarado <<a href="mailto:alvaradojoshua0@gmail.com">alvaradojoshua0@gmail.com</a>> wrote:<br>
>>><br>
>>> In your example the keyword only makes sense if you are shadowing the optional variable. How would unwrap work with a different name?<br>
>><br>
>> It wouldn’t: “unwrap” would never include an equal sign. If you want to do that, use a standard "if let”.<br>
>><br>
>> -Chris<br>
><br>
> So I can stop thinking about this. Gist is here: <a href="https://gist.github.com/erica/db9ce92b3d23cb20799460f603c0ae7c" rel="noreferrer" target="_blank">https://gist.github.com/erica/<wbr>db9ce92b3d23cb20799460f603c0ae<wbr>7c</a><br>
><br>
> -- E<br>
><br>
><br>
> Introducing unwrap<br>
><br>
> • Proposal: TBD<br>
> • Author: Erica Sadun, Chris Lattner, David Goodine<br>
> • Status: TBD<br>
> • Review manager: TBD<br>
> Introduction<br>
><br>
> This proposal introduces unwrap, simplifying common shadowing and allowing a unified syntax for one-item associated values such as Result types.<br>
><br>
> Swift-evolution thread: guard let x = x<br>
><br>
> Motivation<br>
><br>
> Swift lacks a unified, safe way to bind an optional or single-value enumeration to a shadowed varaiable that is guaranteed to be the same name. Introducing unwrap ensures the conditionally bound item does not accidentally shadow any other item.<br>
><br>
> Compare:<br>
><br>
> guard let foobar = foobar else { …<br>
> }<br>
><br>
> guard unwrap foobar else { … }<br>
> Using unwrap eliminates repetition ("foobar = foobar" fails DRY principles) and retains clarity. The keyword is common, simple to understand, and easy to search for if Swift users are unfamiliar with it.<br>
><br>
> This syntax simplifies one-item associated value enumerations by offering a common syntax. Compare:<br>
><br>
> enum Result<T> { case success(T), error(Error<br>
> ) }<br>
><br>
><br>
> guard case let .success(value) = result else { ...<br>
> }<br>
><br>
> guard unwrap result else { ... }<br>
> In the latter case result is bound to the wrapped value. Again, it is simpler and clearer, even with non-Optional types.<br>
><br>
> Detailed Design<br>
><br>
> unwrap can be used with any one-value enumeration. The unwrapped value is bound to the same symbol as the associated type.<br>
><br>
> enum TypeName<T, U> { case anycase(T), anothercase(U) }<br>
><br>
> // First and second are type `TypeName`<br>
> let first = TypeName.anyCase(value1)<br>
> let second = TypeName. anothercase(value2)<br>
><br>
> guard unwrap first else { ... }<br>
> // first is now shadowed as type T<br>
><br>
> guard unwrap second else { ... }<br>
> // second is now shadowed as type U<br>
><br>
> Impact on Existing Code<br>
><br>
> This change is additive and has no impact on existing code other than intentional refactoring.<br>
><br>
> Timeline<br>
><br>
> This proposal is additive and not suited for consideration until Swift 4 phase 2<br>
><br>
> Alternatives Considered<br>
><br>
> • Using a bind keyword. Past discussions were held in the first week of February 2016.<br>
> • Fixing pattern matching grammar<br>
> • Not using this approach<br>
><br>
</div></div><div class="gmail-HOEnZb"><div class="gmail-h5">> ______________________________<wbr>_________________<br>
> swift-evolution mailing list<br>
> <a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
> <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
<br>
______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
</div></div></blockquote></div><br></div></div>