[swift-evolution] [Pitch] Make try? + optional chain flattening work together

Matthew Johnson matthew at anandabits.com
Fri Jan 12 14:07:29 CST 2018


> On Jan 12, 2018, at 2:00 PM, John McCall via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
>> On Jan 12, 2018, at 12:53 PM, BJ Homer via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>> I agree that this behavior is annoying. However, wouldn’t it be source-breaking to change this now?
> 
> Source compatibility means that we can't change the behavior of Swift 3 / Swift 4 source.  This would be a semantic change when building Swift 5 source (or later).  There is no technical reason we couldn't make this change.  It does need to meet a very high bar, because we are trying to avoid making significant semantic breaks.  My personal sense is that it meets that bar because double-optionals can be very confusing for novices and very annoying for everyone else.
> 
> I think most use sites probably do want the optional-collapsing behavior.  'try?' is already "sugar" syntax and should aim to be as convenient as possible for the majority of use cases.  Much like the collapsing done by optional chaining, I think you can come up with examples where somebody would want the non-collapsing behavior, but it doesn't seem unreasonable to say that they just shouldn't use the sugar.

I think I agree with this.  `try?` already has some implicit optional collapsing behavior when it is used in an expression where there is more than one call that can throw.  The most intuitive behavior is for this collapsing to compose with the collapsing of optional chaining.

> 
> John.
> 
>> 
>> -BJ
>> 
>>> On Jan 12, 2018, at 10:25 AM, Russ Bishop via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>> Greetings swift-evolution!
>>> 
>>> There is currently a disconnect between optional chaining and try? when it comes to optional flattening:
>>> 
>>> 
>>> struct SomeType {
>>>     func nonThrow() -> SomeType? { return self }
>>>     func doThrow() throws -> SomeType? { return self }
>>>     func nonOptional() throws -> SomeType { return self }
>>> }
>>> 
>>> let w = SomeType().nonThrow()?.nonThrow()?.nonThrow()?.nonThrow()
>>> // w has type SomeType?
>>> 
>>> let x = try? SomeType().nonOptional().nonOptional().nonOptional().nonOptional()
>>> // x has type SomeType?
>>> 
>>> let y = try! SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
>>> // y has type SomeType?
>>> 
>>> let z = try? SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
>>> // z has type SomeType??
>>> 
>>> 
>>> We get a double-optional only when combining try? and optional-chaining. That is inconvenient and it would be natural to have the compiler do the flattening here.
>>> 
>>> 
>>> If anyone is interested in working on the proposal or implementation please let me know. It would make a nice self-contained task if you're looking to start contributing.
>>> 
>>> 
>>> Russ Bishop
>>>  Simulator
>>> 
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20180112/9b00b9ff/attachment.html>


More information about the swift-evolution mailing list