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

Shawn Erickson shawnce at gmail.com
Thu Mar 10 11:29:30 CST 2016


-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
> <https://github.com/HyperSeb/nil-coalescing-operator/tree/master#introduction>
> Introduction
>
> The current nil coalescing operator can return an optional or not,
> depending on the second parameter.
>
> The prosposed solution is the use of two distinct operators: ?? and ?!.
>
> <https://github.com/HyperSeb/nil-coalescing-operator/tree/master#motivation>
> 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.
>
> <https://github.com/HyperSeb/nil-coalescing-operator/tree/master#proposed-solution>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 ?? tertiaryFallbackvar nonOptionalValue = someArray ?? someFallback ?? secondaryFallback ?! tertiaryFallback
>
>
> <https://github.com/HyperSeb/nil-coalescing-operator/tree/master#detailed-design>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.
>
> <https://github.com/HyperSeb/nil-coalescing-operator/tree/master#impact-on-existing-code>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.
>
> <https://github.com/HyperSeb/nil-coalescing-operator/tree/master#alternatives-considered>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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160310/909ea86a/attachment.html>


More information about the swift-evolution mailing list