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

Xiaodi Wu xiaodi.wu at gmail.com
Thu Sep 8 04:43:57 CDT 2016


>
> That sounds pretty good to me, actually. It removes one category of
real-world bugs without fundamentally upending Swift operators. Neat
solution regarding separation of | and ^.


On Thu, Sep 8, 2016 at 04:08 Pyry Jahkola <pyry.jahkola at iki.fi> wrote:
>
>> To stay slightly on topic of the original Subject line, I'd point out
>> that no one has yet demonstrated an example where the current precedence
>> position of `??` causes bugs at runtime.
>>
>> The original motivation by Erica simply failed to compile without the
>> parentheses, so it wasn't about confusion so much as about mere
>> convenience. And there exist actual uses where the current precedence
>> brings greater convenience, e.g. when the RHS expression contains
>> arithmetic operations.
>>
>> Like Wux, I also don't think we have any reason to adjust the precedence
>> of `??` from what it is.
>>
>> * * *
>>
>> But then, I also think we should do something to our bitwise ops:
>>
>> On 08 Sep 2016, at 09:58, Xiaodi Wu via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> You and I seem to agree that `let i = 4 << 1 + 3` is rather reasonable.
>>
>>
>> Here, I would actually differ somewhat. If there's something that ought
>> to be higher in precedence than `+` and `*`, IMO that would be actual
>> exponentiation, which could be approximated in a math library by the
>> presently missing `**` operator, for example.
>>
>> I am not sure how one can make an unintended error either reading or
>> writing this line of code[*].
>>
>> [*] Actually, I can see precisely one way to make such an unintended
>> error, since I have actually done so. It has to do with Swift having moved
>> away from the classical C-family operator precedence table. I would
>> actually not be opposed to making changes that guard against such an error.
>>
>>
>> There's a fair amount of C code out in the wild that is going to be
>> migrated into Swift in the near future. And that code would benefit if
>> Swift's precedence rules didn't unexpectedly break from C – that is, not
>> without the programmer's awareness.
>>
>> The key differences to C that I think will cause confusion in Swift are:
>>
>> A) Unlike C, Swift defines `<<` and `>>` with the highest precedence.
>> B) Unlike C, Swift defines `&` at multiplication precedence (`*` etc.).
>> C) Unlike C, Swift defines both `^` and `|` at equal precedence to each
>> other, and that is the precedence of addition (`+` etc.).
>>
>> Other than that, we also use equal precedence for all comparison
>> operators but at the same time remove their associativity, so that can't
>> cause runtime problems (as such code would fail to compile). Here's a full
>> table, with the notable differences marked with a red comment:
>>
>> *Infix operators in C*
>> *In Swift 3*
>> // skipping unary ops etc
>>
>> *  /  %
>> *             <<  >>       // (!)*
>> +  -
>>       *  &*  /  %  *&      // (!)*
>> <<  >>
>>      +  &+  -  &-  *|  ^   // (!)*
>> <  <=  >  >=
>> ...  ..<
>> ==  !=
>> as  as?  is
>> &
>> ??
>> ^
>> <  <=  >  >=  ==  !=  ===  !==  ~=
>> |
>> &&
>> &&
>> ||
>> ||
>> (default precedence diverges here)
>> ?:
>> ?:
>> =  @= // for various `@`
>> =  @= // for various `@`
>> ,
>> ->
>>
>> I think Jacob has a point in separating bitwise operations into their own
>> hierarchy. I'd recommend doing so all the way, but retaining `&` with a
>> higher "bitwise-multiplicative" precedence:
>>
>> 1) Move `|` and `^` into their own parallel precedence groups named
>> *BitwiseOr* and *BitwiseXor*, just above RangeFormation.
>> 2) Move `&` into its own group *BitwiseAnd*, just above both BitwiseOr
>> and BitwiseXor.
>> 3) Move *BitwiseShift* (i.e. `<<` and `>>`) just above BitwiseAnd.
>>
>> That would make it so that rarely occurring*) expressions mixing `^` and
>> `|` would now need parenthesising, but either of them would work together
>> with `&`, `<<`, and `>>` just like they do in C (and just the way binary
>> addition relates to multiplication in the conventions of mathematics).
>>
>> *) E.g. none found in https://graphics.stanford.
>> edu/~seander/bithacks.html.
>>
>> Also integer arithmetic would stay clearly separated from bitwise
>> operations, which in my experience is the source of most bugs and
>> confusion. E.g. the expressions `a & b + c`, `a | b + c`, and `a << b - c`
>> all compile in both C and Swift, but are parsed in exactly opposing ways.
>>
>> The whole hierarchy I'm proposing is illustrated in the attachment below,
>> with all changes found in the top part above RangeFormation.
>>
>> — Pyry
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160908/e85e801f/attachment-0001.html>


More information about the swift-evolution mailing list