[swift-evolution] [Review] SE-0024 "Optional Value Setter `??=`"

David Waite david at alkaline-solutions.com
Sun Feb 14 01:52:35 CST 2016


> What is your evaluation of the proposal?
-1, on the basis of use being a potential anti-pattern, and the spec focusing on the benefit of a terser syntax over possible uses.

If there are additional uses outside the proposal, this evaluation may change.

> Is the problem being addressed significant enough to warrant a change to Swift?
Not as described. 

“??” is described as the nil coalescing operator.  It is defined as the following function:

public func ??<T>(optional: T?, @autoclosure defaultValue: () throws -> T) rethrows -> T
The purpose of the nil coalescing operator is defined as follows by the Swift Programming Language book

“The nil coalescing operator (a ?? b) unwraps an optional a if it contains a value, or returns a default value b if a is nil. The expression a is always of an optional type. The expression b must match the type that is stored inside a.”

This operator has thus two core properties:
1. it allows another mechanism to deal with nil values, by specifying an alternate value to use in the nil case
2. as either the value or the alternate is non-nil, it casts off optionality

This operator does not do the second. It allows you to apply a value in the nil case, but the resulting value is still an optional. As such, I fear the usefulness of the “??=“ operator is greatly diminished.

Note also that unlike other operators with inout equivalents like addition, the type of the left-hand input and the output are not the same in “??” due to the missing safe casting off of optionality.

> Does this proposal fit well with the feel and direction of Swift?
The example given by the proposal is as follows:

really.long.lvalue[expression] = really.long.lvalue[expression] ?? ""

In this case, you are setting a default value of “” to an optional target within a long expression.

However, it is unclear why the original expression allowed nil, or why setting this value to “” is an improvement.

To counter, some existing usage:

let userDefaults = NSUserDefaults.standardUserDefaults()
let repeatCount = userDefaults.valueForKey("repeatCount") as? Int ?? 4
for attempt in 0..<repeatCount {
    // ...
}

The for loop only works because repeatCount is non-optional. Assigning the value back into the expression would mutate the original value, but would still require one to cast off the optionality of the value.

> If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
As mentioned, Ruby has a similar behavior. Other than the “false” and “nil” literal values, everything evaluates as true. The || and && operators preserve the values of the lhs and rhs arguments.

1 && 2 # is 2
1 || 2    # is 1
nil || 2  # is 2

As such, ||= can be used for such a default assignment system.

However, ruby does not have optionality. All libraries must take into account the possibility of sending nil in for a value. As such, it is not influenced by the limitations of this proposal.
 
> How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
In-between a reading and a study.

-DW

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160214/4f0d321b/attachment.html>


More information about the swift-evolution mailing list