[swift-evolution] [Last second] Precedence of nil-coalescing operator seems too low

Andrey Fidrya af at zabiyaka.com
Fri Sep 9 01:06:43 CDT 2016


Pyry,

> Let me put it differently: I still haven't seen, nor was I able to conceive myself, a realistic example where `??` would cause problems.


An example of broken code from real project:

let allParameters: [String: Any?] =
 defaultParameters["sendMessage"] ?? [:] +
 parameters +
 ["chat_id": chat_id, "text": text]

I think that the precedence of ?? is counter-intuitive because it's mainly used as
nil-unwrapping operator and there are often multiple optionals in an expression.
It's too easy to make errors like this one:

let value = x ?? defaultX + y ?? defaultY
let value = x ?? (defaultX + y ?? defaultY)

Imho braces should be required in these expressions.

Even this expression is confusing and in my opinion would only benefit from
braces:
let value = x ?? defaultX + modifier

Also, low precedence of ?? is a source of confusion in other languages, for example:
http://www.codeproject.com/Tips/721145/Beware-The-null-coalescing-operator-is-low-in-the <http://www.codeproject.com/Tips/721145/Beware-The-null-coalescing-operator-is-low-in-the>
but in C# this operator isn't used as often as in Swift, so it's not a major issue there.

Andrey


> On 08 Sep 2016, at 15:20, Pyry Jahkola via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Vladimir,
> 
> I don't disagree with you about bitwise operations (please read my email again). I'm saying when it comes to `??`, we don't have the evidence necessary for proposing a breaking change.
> 
>> On 08 Sep 2016, at 14:21, Vladimir.S <svabox at gmail.com <mailto:svabox at gmail.com>> wrote:
>> 
>> Why do you need to see some precedence (…) while this construction is so simple and obviously would be used often and *will* cause bugs. (…)
> 
> Let me put it differently: I still haven't seen, nor was I able to conceive myself, a realistic example where `??` would cause problems.
> 
>>> The original motivation by Erica simply failed to compile (…)
>> 
>> Sorry, but you are just not right.
> 
> Let me remind you that the original motivation from Erica wasn't about which way `foundIndex ?? lastIndex + 1` goes but about whether `let y = 5 + x ?? 2` compiles at all.
> 
>> The code compiles without even warning:
>> 
>> let foundIndex : Int? = 1
>> let lastIndex = 2
>> 
>> let nextIndex = foundIndex ?? lastIndex + 1
> 
> It certainly does compile. But is it realistic? Look at the variable names: does this code make any sense at all? What is `lastIndex`? What is `lastIndex + 1`? Why not `things.endIndex`? Indeed, why not:
> 
>     let foundIndex: Int? = things.index(of: something)
>     let nextIndex = foundIndex.map { $0 + 1 } ?? things.endIndex
> 
> That said, I give you the benefit of the doubt – I still believe there can be examples where `??` may be confusing. But without seeing any such examples from the real world, I don't think we have a case for changing `??`.
> 
>> After I showed the code compiles, would you change your opinion?
> 
> No, not with these examples.
> 
> * * *
> 
> Finally:
> 
>> IMO the best solution (…) would be to require (…) parenthesis when operators from different groups are mixed in the same expression. IMO no need in complex rules to make Swift safer. I.e. when you have a = 10 + 5 * 10 - you don't need parenthesis, when you have a = b << 4  - also all is ok, but if you have a = b << 4 + 5 * 10 - you'll have a warning until add parenthesis to make your intention clear. (…)
> 
> Look, changing how `b << 4 + 5 * 10` is compiled is exactly what I was proposing. With my changes, it would become a compiler error. IMO, it ought to be parenthesised explicitly as either
> 
>     (b << 4) + 5 * 10
> 
> or
> 
>     b << (4 + 5 * 10)
> 
> depending on which one was intended.
> 
> — Pyry
> 
> _______________________________________________
> 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/20160909/92540d0b/attachment.html>


More information about the swift-evolution mailing list