[swift-evolution] [Discussion] Breaking precedence

Xiaodi Wu xiaodi.wu at gmail.com
Tue Aug 2 13:34:52 CDT 2016


On Tue, Aug 2, 2016 at 1:09 PM, Nevin Brackett-Rozinsky <
nevin.brackettrozinsky at gmail.com> wrote:

> @Xiaodi
> Actually, I think just about all the rest of the precedence rules “make
> sense” intuitively:
>

Disagree vehemently. See below:


> `a | b == c % d`
> `a < b ? c : d * e`
>

I, like you, know what this means; but it is out of habit, not intuition.
There have been people *on this very list* who have argued in the past that
ternary operator precedence is unintuitive and that parentheses should be
required. To them, the more intuitive (and counterfactual) meaning of the
above is`a < (b ? c : d) * e`.


> `a ?? b - c`
>

Here, I'm in the exact scenario you mentioned about bitwise operators. I
literally do not recall, staring at this statement, whether it's `(a ?? b)
- c` or `a ?? (b - c)`. I actually look this up every time.


> `a...b+c`
>
> These all do what they ought to, and of course assignment naturally has
> low precedence.
>

Naturally. Also, essentially how it works in math.


> Really the only confusing ones are operators that “seem like peers” but
> actually have different precedences. Namely the two groups I mentioned:
> logical operators and bitwise operators.
>

Which brings me to my original question: aren't you really saying that
people should not be required to *learn* any rules of precedence beyond
those of basic arithmetic? Put another way, unless you learned it in
elementary school math or can "intuit" the result--usually because the
alternative interpretations wouldn't even typecheck--then there should be
no precedence relationship?


>
> @Daniel
> Making it easy to write code that is unclear to other people who read it,
> is an explicit anti-goal for Swift.
>
> Nevin
>
>
> On Tue, Aug 2, 2016 at 1:42 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
>> This is an expansive argument you advance. Should users be expected to
>> learn *any* rules of precedence beyond those of basic arithmetic? It would
>> seem that you are arguing no. Yet Swift just went through an arduous
>> redesign to permit--nay, improve--exactly that.
>>
>> On Tue, Aug 2, 2016 at 12:30 Nevin Brackett-Rozinsky <
>> nevin.brackettrozinsky at gmail.com> wrote:
>>
>>> 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.
>>>
>>> Nevin
>>>
>>>
>>> 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/912d8a48/attachment.html>


More information about the swift-evolution mailing list