On 05.09.2016 23:19, Xiaodi Wu via swift-evolution wrote:
This suggestion has been pitched earlier and I've expressed my opinion in
those earlier threads, but I'll repeat myself here:

I'm hugely opposed to such changes to the precedence table. Those of us who
work with bitwise operators on a regular basis have memorized their
precedence in Swift (and other languages) and rely on such precedence to
write readable, correct code without excessively nested parentheses. Any
change here would break existing, carefully constructed code, punishing
those who *have* put in the effort to learn the precedence table. To any

FWIW, I can't understand such an opinion. From my view this is a fragile code, you are saying about *writing* of the code, but code will be read much often than written.

The question is not how *you* good as developer and if *you* rememebered *all* precedence in Swift, but how many *bugs* will you have in 3rd party code, written by someone who not as good as you or probably just loose the concentration for one moment and written incorrect logic just because it s *so easy* to make such kind of mistakes. And also the question is how your code will be understood by some other developer who will *read* your code and probably *modify* it later.

Currently we can have such a code:

let nextIndex = foundIndex ?? lastIndex + 1

let result = a || (b) ? isOne() : isTwo()

s << (x == 10) ? "10" : "not 10"

let i = 4 << 1 + 3

If we'll ask here in list for results for these lines, I believe we'll have a big number of people who will not answer correctly.

Swift *requires* to be careful in some situations, for example when working with Integer types, you can't "just" add Int and Int8, you have to explicitly case. Why? Because IMO Swift want to be safe(as much as possible) language, which helps to produce code without surprises, where you explicitly show your intention.

Do you really believe that the above code is clear about the intention of the developer and the *ability* to write such code don't open the door to hard-find bugs in code(not in your code, of course)

And about lints. They can help only for your own code in project.
Even if you added 3rd party code to your project as source, with lint you'll have to change all of such code and analyze logic in each questionable line (if this line is correct or there is a logical error). Plus, if you add 3rd party code as compiled framework/module you can't check it at all.

Yes, I do believe that Swift should require a parenthesis for any expression, where it is not clear what is the order of operations. Probably when we have an operations of different groups in the same expression. Exactly for the same reason - to make developer be clear about the intention of such code:

let nextIndex = foundIndex ?? (lastIndex + 1)

let result = a || ((b) ? isOne() : isTwo())

s << ((x == 10) ? "10" : "not 10")

let i = 4 << (1 + 3)

IMO much clear, I see *no* visual problems because of added parenthesis, only increased readability and my "parser" in head processes this faster

Again, there were (fixed now, I believe) a lot of logical errors(bugs) in well-known open source projects(I do believe there was code review for them and code most likely written by well-skilled developers) because of possibility to mix different groups of operators in same line without parenthesis (for example in Chromium,ReactOS,MongoDB,Apache Xerces Project,Unreal Engine 4,Wine,FreeBSD Kernel,Open X-Ray Engine,OpenJDK,CryEngine V,GCC). Again, not just because C allows to treat boolean values as integers, but because of mixing of operators.

I do believe Swift should be the language that prevent such "possible-buggy" code in all areas.

So, my suggestion is: produce a warning when operators from different groups mixed in the same expression without parenthesis. Or let's discuss another condition/method. This will not break the "old" code, but if you want to write not clear code and don't want to be explicit about your intention - you will produce code with warnings. Fair enough, I think.

Such kind of bugs is hard-to-find and IMO it is worth to have "warning" and to add parenthesis to prevent them not only in *your* code, but also in any 3rd party code or in compiled framework/module.

To all: please provide your opinions on this subject, so we all can see if a lot of developers support my opinion(or don't).
Thank you for reading this.

other user of Swift, it should come as no surprise that operators *have*
precedence and associativity, and it is not such a burden for a user either
to memorize or to consult a table for these properties when they are unsure.

There is no way whatsoever to use intuition to arrive at the exact
precedence of `??`, or `as`,or `&&`, or `||`, or `&`, or `|`, or `^` or
`<<`, or `>>`, and there will be no relative precedence that will prove
intuitive to all. (That said, there is a rational basis for the relative
precedence of `&`, `|`, and `^` to each other.) If you believe this
situation to be problematic, then you must conclude that we should remove
relative precedence between any operators except perhaps the basic
arithmetic operators `+`, `-`, `*`, `/`. This line of reasoning would be a
huge U-turn from the direction of Swift, which after all just revised the
syntax with which custom operator precedence is defined. Such a feature
would be totally out of place in a language where operators other than
those for basic arithmetic are not supposed to have precedence relations
with each other.

(Of course, the relative precedence of arithmetic operators is in some ways
arbitrary as well, though it is inherited from math that everyone knows.
How did you learn it in the first place? You memorized it.)


On Mon, Sep 5, 2016 at 2:47 PM, Erica Sadun via swift-evolution
<[email protected] <mailto:[email protected]>> wrote:

    At this point, I'm not sure whether this is an -evolution question or a
    -dev question. The latter would be much easier to work on at this time
    and could potentially be postponed to a dot release. I know that any
    conversation not directly related to 3.0 right now is a Bad Thing.

    And I suspect that Steven C is probably the right person to know about
    wrangling precedence and existing standards.

    -- E


    On Sep 5, 2016, at 12:30 AM, Jacob Bandes-Storch <[email protected]
    <mailto:[email protected]>> wrote:

    Now you've gotten me thinking about precedence of other operators too.

    Since ?? is prone to causing confusion in either direction (cf. your
    example and my example), it could be put in its own group whose
    relation to the numeric operators is intentionally undefined (thus
    requiring parens).

    I don't know about other folks, but I'll certainly get confused if &
    and | and ^ are mixed. What if we removed their relation to each
    other (requiring parens when mixing them)?

    <proposed-precedence.png>

    For comparison (ha), here's what we have today:

    <current-precedence.png>

    Jacob

    On Sat, Sep 3, 2016 at 10:20 PM, Erica Sadun <[email protected]
    <mailto:[email protected]>> wrote:

        On Sep 3, 2016, at 10:15 PM, Jacob Bandes-Storch
        <[email protected] <mailto:[email protected]>> wrote:

        Perhaps-conversely, what should this code do?

            let nextIndex = foundIndex ?? lastIndex + 1

        Jacob

        It's a good counter example. And there's no optional-associative
        option.

        -- E


        On Sat, Sep 3, 2016 at 9:05 PM, Erica Sadun via swift-evolution
        <[email protected] <mailto:[email protected]>>
        wrote:

            Given: `let x = Optional(3)` then

                `let y = 5 + x ?? 2` will not compile

            but

                `let y = 5 + (x ?? 2)` will.


            Should NilCoalescingPrecedence be raised? The current
            operator precedence chain is:

                BitwiseShiftPrecedence > MultiplicationPrecedence >
                AdditionPrecedence > RangeFormationPrecedence >
                CastingPrecedence > NilCoalescingPrecedence >
                ComparisonPrecedence > LogicalConjunctionPrecedence >
                LogicalDisjunctionPrecedence > TernaryPrecedence >
                AssignmentPrecedence > FunctionArrowPrecedence > [nothing]


            It seems to me that `NilCoalescingPrecedence` should
            probably be higher than `MultiplicationPrecedence` and
            possibly higher `BitwiseShiftPrecedence` as its job is to
            produce an unwrapped value that can then be operated upon.

            I think CastingPrecedence should be even higher because

                `expression as? T ?? fallback value`

            should be parsed as

                `(expression as? T) ?? (fallback value)`


            I apologize profusely because I know this is beyond last minute,

            -- E


            _______________________________________________
            swift-evolution mailing list
            [email protected] <mailto:[email protected]>
            https://lists.swift.org/mailman/listinfo/swift-evolution
            <https://lists.swift.org/mailman/listinfo/swift-evolution>






    _______________________________________________
    swift-evolution mailing list
    [email protected] <mailto:[email protected]>
    https://lists.swift.org/mailman/listinfo/swift-evolution
    <https://lists.swift.org/mailman/listinfo/swift-evolution>




_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to