[swift-evolution] [Discussion] Breaking precedence

Nevin Brackett-Rozinsky nevin.brackettrozinsky at gmail.com
Tue Aug 2 12:30:49 CDT 2016

Speaking for myself, I will *never* remember which of `&&` and `||` has
higher precedence. I think of them as peers, so I always use parentheses
around them, and whenever I read code that mingles them without parentheses
its meaning is *unclear* to me.

One of Swift’s main goals is clarity at the point of use. After all, code
is read far more often than it is written. To me, an expression like `a &&
b || c && d` is not clear when I read it.

The same goes for bitwise operators: I view them as peers. I do not think
of them as “additive” or “multiplicative” (and definitely not
“subtractive”), so code that relies on their precedences will always send
me scrambling to look up which comes first.

Certainly something like `a + b | c & d - e * f ^ g` is meaningless to me
without parentheses.


On Tue, Aug 2, 2016 at 12:08 PM, Xiaodi Wu via swift-evolution <
swift-evolution at swift.org> wrote:

> That's an excellent point, actually. Would there be downsides not yet
> considered?
> On Tue, Aug 2, 2016 at 11:03 Félix Cloutier <felixcca at yahoo.ca> wrote:
>> These expressions mix two types of logic that have different
>> implications. For instance, `a * 16` and `a << 4` are "mostly equivalent",
>> except that `a * 16` will crash on overflow. In these cases, I find that
>> grouping provides some visual insulation that groups off the somewhat
>> subtle differences.
>> Félix
>> Le 2 août 2016 à 08:49:07, Xiaodi Wu <xiaodi.wu at gmail.com> a écrit :
>> On Tue, Aug 2, 2016 at 10:41 AM, Félix Cloutier <felixcca at yahoo.ca>
>> wrote:
>>> I don't think that "intuitive" or "non-intuitive" is what you'd be
>>> looking for. There is nothing intuitive about multiplications having a
>>> higher precedence than additions; it's just a matter of conventions. I'm
>>> not a maths expert (as Stephen showed, I didn't even give the right
>>> explanation to binary operators!), but it seems to me that there could well
>>> be a parallel universe in which additions have precedence over
>>> multiplications without other serious implications.
>>> And as it happens, a majority of people don't know that there is one for
>>> binary operators. I believe that the right question should be: do we want
>>> to pretend that this convention doesn't exist, to the benefit of people who
>>> don't know about it, and the detriment of those who do? Also, do we want to
>>> break it for && and || too?
>>> I think that the biggest use case for binary operators in other
>>> languages are flags, and in Swift we treat these as collections. I'd
>>> venture that &, | and ^ would show up about as frequently as UnsafePointers
>>> and the like. It seems to me that Swift's approach has been to make things
>>> easy by default without locking away the power tools, and my personal
>>> expectation is that if you have to write code that has binary operators
>>> despite everything else that Swift has for you, you can be bothered to
>>> learn a precedence rule.
>>> That said, one thing that I could definitely get behind is breaking
>>> precedence between binary operators and arithmetic operators. I don't think
>>> that it makes sense to write something like "a & b / c". Looking at my
>>> code, the only place where I needed to mix binary operators and arithmetic
>>> operators were `a & (a - 1)` (results in 0 if a is a power of two), and
>>> that one needs parentheses anyway.
>> Although here, your same argument applies. If you need to write `a & b /
>> c`, then you can be bothered either to learn or look up a table, or you can
>> just put in the parenthesis yourself. Likewise, if you're a reader of the
>> code, it's highly likely that this is a complex formula anyway; you can
>> either know the relative precedence or look it up, but that's the *least*
>> of your worries in terms of what it will take to understand that code. I
>> see no reason to force parentheses unless it actually prevents user error.
>>> Félix
>>> Le 2 août 2016 à 02:29:41, Anton Zhilin <antonyzhilin at gmail.com> a
>>> écrit :
>>> 2016-08-02 7:18 GMT+03:00 Félix Cloutier <swift-evolution at swift.org>:
>>>> I disagree. The binary operators have properties that are comparable to
>>>> arithmetic operators, and their precedence is easy to define as such. & has
>>>> multiplication-like properties (0*0=0, 0*1=0, 1*0=0, 1*1=1); | has
>>>> addition-like properties (0+0=0, 0+1=1, 1+0=1, 1+1=2); ^ has
>>>> subtraction-like properties (0-0=0, 0-1=-1, 1-0=1, 1-1=0), and their
>>>> precedences are set accordingly (& is multiplicative, | and ^ are additive).
>>>> The same applies to && and ||. Bit shifts are exponentiative.
>>> I believe that such way of thinking is non-intuitive. In C, bitwise
>>> operators are not intervened by any others, except for comparison operators
>>> (agreed, it was a mistake). We now have possibilities to do so in Swift,
>>> even better. I suggest to branch off right before AdditionPrecedence:
>>> RangeFormation < Addition < Multiplication
>>> RangeFormation < BitwiseOr < BitwiseAnd < LogicalShift
>>> Another concern is NilCoalescing, which can be though to be semantically
>>> similar to Ternary. And at the same time it looks like || and &&, which
>>> would bring it between LogicalConjunction and Comparison.
>>> Also, do Casting and RangeFormation stand where they should?
>>> Next, Ternary operator is unique. Noone would ever like to put operators
>>> in this precedence group, because it would be confusing. Why not simplify
>>> our model and say that ?: has lower precedence than all binary operators,
>>> including Assignment? Unary > binary > ternary, sounds good?
> _______________________________________________
> 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/20160802/c9d0a0db/attachment.html>

More information about the swift-evolution mailing list