[swift-evolution] Make distinction between ?? -> T and ?? -> T?

Step C schristopher at bignerdranch.com
Thu Mar 10 22:48:49 CST 2016


-1. 

Jordan explained the meaning of ! In Swift. For those reasons "?!" Does not work as an operator for non-optional. 

But further, optionals work in Swift by providing just enough explicitness without too much friction. This operator makes a distinction that is not sufficiently valuable beyond what the type system already provides. Comments below on the example. 

>> Am 10.03.2016 um 18:29 schrieb Shawn Erickson via swift-evolution <swift-evolution at swift.org>:
>> 
>> -1 on ?! since it doesn't trap like others uses of !
>> -1 on the need for this, the compiler won't let you do the wrong thing here, yeah I understand that at a glance a human can't quickly tell however the same thing happens things that return an option when assigned into a var/let
>> 
>>> On Thu, Mar 10, 2016 at 9:23 AM Jordan Rose via swift-evolution <swift-evolution at swift.org> wrote:
>>> I forgot to mention it but I'm (also?) very much against adding a new operator with "!" in the name that won't ever trap. The "not" operator got pulled in from C, but every other use of "!" means "I am asserting I know more than the compiler does" (or perhaps more accurately "there is a precondition here that the compiler doesn't know about"). That includes !-to-unwrap, ImplicitlyUnwrappedOptional, 'as!', and 'try!'.
>>> 
>>> Jordan
>>> 
>>> 
>>>> On Mar 10, 2016, at 4:49 , Sébastien Blondiau via swift-evolution <swift-evolution at swift.org> wrote:
>>>> 
>>>> Here is my proposal:
>>>> 
>>>> Distinction between ?? -> T? and ?? -> T
Snip
>>>> Motivation
>>>> 
>>>> Currently, the only nil coalescing operator may return an optional value or not. This variability can leads to unclear line of code:
>>>> 
>>>> var result = value ?? otherValue
>>>> where result may be an optional, and cannot be determined without looking for the definition of otherValue.
>>>> 
>>>> A real situation where I found the unique operator confusing was something like that:
>>>> 
>>>> func someFunction() -> T {
>>>> 
>>>>     var someValue: T
>>>> 
>>>>     /* some code */
>>>> 
>>>>     var value = someOptionalValue ?? someValue
>>>> 
>>>>     /* some code */
>>>> 
>>>>     return value
>>>> }
>>>> For some reasons, I had to consider a new case where someValue had to be an optional
>>>> 
>>>> func someFunction() -> T {
>>>> 
>>>>     var someValue: T?
>>>> 
>>>>     /* some code */
>>>> 
>>>>     var value = someOptionalValue ?? someValue
>>>> 
>>>>     /* some code */
>>>> 
>>>>     return value    // error: value of optional type 'T?' not unwrapped; did you mean to use '!' 
>>>> }
>>>> In my situation, the error was not at the return line but rather at the declaration of value. value was non optional in the first code and implicitly became optional in the second code.
>>>> 
But the type system gave you an error.  Easy enough to find where the optional is coming from, and not unreasonable that the compiler can't tell which bit of this logic was the incorrect part. I think this is essential complexity, the price we pay (of having optionals and having to reason about them) is worth it and unavoidable for the benefit of having this method as it was originally - with no optional values. 

(End of my reply)


>>>> Proposed solution
>>>> 
>>>> A new operator ?! , which take a non optional second parameter and return a non optional value. This new operator replaces the current ?? which return a non optional.
>>>> 
>>>> This ensures the programmer knows if whether the value is optional or not:
>>>> 
>>>> var value = someOptionalValue ?? someValue  // value is optional, without depending on someValue optionality
>>>> 
>>>> var value = someOptionalValue ?! someValue  // value is not optional
>>>> // but if someValue is optional then this produces an error
>>>> The nil coalescing chaining benefits the same clarity:
>>>> 
>>>> var optionalValue    = someArray ?? someFallback ?? secondaryFallback ?? tertiaryFallback
>>>> var nonOptionalValue = someArray ?? someFallback ?? secondaryFallback ?! tertiaryFallback
>>>> Detailed design
>>>> 
>>>> Under this proposal, the ?! operator has a lower precedence than ?? to have the described form of chaining: the operator ?! returns a non optional after that ?? has returned an optional.
>>>> 
>>>> infix operator ?? { associativity right precedence 131 }
>>>> 
>>>> +infix operator ?! { precedence 130 }
>>>> The ?! operator is non associative to avoid bad usages, which would lose some interest of the new operator:
>>>> 
>>>> -var nonOptionalValue = someArray ?! someFallback ?! secondaryFallback ?! tertiaryFallback
>>>> +var nonOptionalValue = someArray ?? someFallback ?? secondaryFallback ?! tertiaryFallback
>>>> Only the function ?? which returns a non optional is replaced:
>>>> 
>>>> -public func ??<T>(optional: T?, @autoclosure defaultValue: () throws -> T) rethrows -> T
>>>> +public func ?!<T>(optional: T?, @autoclosure defaultValue: () throws -> T) rethrows -> T
>>>> The internal implementation do not need to change.
>>>> 
>>>> Impact on existing code
>>>> 
>>>> This proposal will impact every code using the nil coalesing operator to get a non optional value.
>>>> 
>>>> The migration can be done automatically by replacing all ?? which currently return non optional value.
>>>> 
>>>> Alternatives considered
>>>> 
>>>> There are currently no alternatives considered.
>>>> 
>>>> Thoughts?
>>>> 
>>>> --
>>>> Sébastien Blondiau
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> 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
>> _______________________________________________
>> swift-evolution mailing list
>> 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/20160310/248bac54/attachment.html>


More information about the swift-evolution mailing list