<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Sep 7, 2016 at 8:11 AM, Vladimir.S <span dir="ltr"><<a href="mailto:svabox@gmail.com" target="_blank">svabox@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>On 05.09.2016 23:19, Xiaodi Wu via swift-evolution wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This suggestion has been pitched earlier and I've expressed my opinion in<br>
those earlier threads, but I'll repeat myself here:<br>
<br>
I'm hugely opposed to such changes to the precedence table. Those of us who<br>
work with bitwise operators on a regular basis have memorized their<br>
precedence in Swift (and other languages) and rely on such precedence to<br>
write readable, correct code without excessively nested parentheses. Any<br>
change here would break existing, carefully constructed code, punishing<br>
those who *have* put in the effort to learn the precedence table. To any<br>
</blockquote>
<br></span>
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.<br>
<br>
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.<br>
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.<br>
<br>
Currently we can have such a code:<span><br>
<br>
let nextIndex = foundIndex ?? lastIndex + 1<br>
<br></span>
let result = a || (b) ? isOne() : isTwo()<br>
<br>
s << (x == 10) ? "10" : "not 10"<br>
<br>
let i = 4 << 1 + 3<br>
<br>
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.<br></blockquote><div><br></div></div></div></div><div style="white-space:pre-wrap">(a) I don't believe so; (b) even if that were the case, it's *learnable* (i.e. once you have learned it once, it is possible to remember); (c) it is not the right test--there are plenty of functions that people would struggle to understand without consulting documentation; but no one writes or reads code using only Notepad, and with the use of a single table, *everyone* can answer correctly. Compare this to the situation with existentials, which involves high-level concepts regarding type systems: it would take much more than a single table to help someone understand why Self or associated type constraints prevent you from doing certain things with protocols.</div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
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.<br></blockquote><div><br></div></div></div></div><div style="white-space:pre-wrap">I believe safe promotions are coming to Swift eventually; some of this is intentional, but not all of the strictness here is by design.</div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
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)<br>
<br>
And about lints. They can help only for your own code in project.<br>
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.<br>
<br>
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:<br>
<br>
let nextIndex = foundIndex ?? (lastIndex + 1)<br>
<br>
let result = a || ((b) ? isOne() : isTwo())<br>
<br>
s << ((x == 10) ? "10" : "not 10")<br>
<br>
let i = 4 << (1 + 3)<br>
<br>
IMO much clear, I see *no* visual problems because of added parenthesis, only increased readability and my "parser" in head processes this faster<br></blockquote><div><br></div></div></div></div><div style="white-space:pre-wrap">There is nothing today that prevents you, or any careful developer, from using the parentheses *as necessary*, and all evidence points to people using parentheses as necessary and wisely. I am *not arguing* that these parentheses are not good. However, if you remove precedence relations, then you are *forcing* everyone to use parentheses, always, in all situations. Unlike other parts of Swift, it isn't even possible to extend existing precedence groups that don't have relations, like it's possible to extend types you don't own.</div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
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.<br></blockquote><div><br></div></div></div></div><div style="white-space:pre-wrap">Can you provide examples that show this? The real-world example you provided could not happen in Swift. Since you say that you know of lots of logical errors that result from mixing of operators in these projects, can you provide some examples from these projects that would also arise in Swift? If so, you would persuade me of the problem.</div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
I do believe Swift should be the language that prevent such "possible-buggy" code in all areas.<br>
<br>
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.<br></blockquote><div><br></div></div></div></div><div style="white-space:pre-wrap">I think you are describing exactly the function of a linter.</div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
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.<br>
<br>
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).<br></blockquote><div><br></div></div></div></div><div style="white-space:pre-wrap">Previous threads have shown opinions on both sides.<br><br>In the period of a few months, there have been proposals to change the precedence and to remove the precedence of <<, >>, &, | ^, is, as, ??, ..<, ..., &&, ||, ?:. This represents *all* non-arithmetic, non-comparison, non-assignment operators.<br><br>The promise of Swift 3 was that going forward, only essential source-breaking changes would occur; here, nothing about operators has changed since version 1, yet all of a sudden we are considering how to fundamentally alter how they work. Existing code *will break*, and sometimes silently, if such changes are made.</div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Thank you for reading this.<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>
other user of Swift, it should come as no surprise that operators *have*<br>
precedence and associativity, and it is not such a burden for a user either<br>
to memorize or to consult a table for these properties when they are unsure.<br>
<br>
There is no way whatsoever to use intuition to arrive at the exact<br></span>
precedence of `??`, or `as`,or `&&`, or `||`, or `&`, or `|`, or `^` or<span><br>
`<<`, or `>>`, and there will be no relative precedence that will prove<br>
intuitive to all. (That said, there is a rational basis for the relative<br>
precedence of `&`, `|`, and `^` to each other.) If you believe this<br>
situation to be problematic, then you must conclude that we should remove<br>
relative precedence between any operators except perhaps the basic<br>
arithmetic operators `+`, `-`, `*`, `/`. This line of reasoning would be a<br>
huge U-turn from the direction of Swift, which after all just revised the<br>
syntax with which custom operator precedence is defined. Such a feature<br>
would be totally out of place in a language where operators other than<br>
those for basic arithmetic are not supposed to have precedence relations<br>
with each other.<br>
<br>
(Of course, the relative precedence of arithmetic operators is in some ways<br>
arbitrary as well, though it is inherited from math that everyone knows.<br>
How did you learn it in the first place? You memorized it.)<br>
<br>
<br>
On Mon, Sep 5, 2016 at 2:47 PM, Erica Sadun via swift-evolution<br></span><span>
<<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> <mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>>> wrote:<br>
<br>
At this point, I'm not sure whether this is an -evolution question or a<br>
-dev question. The latter would be much easier to work on at this time<br>
and could potentially be postponed to a dot release. I know that any<br>
conversation not directly related to 3.0 right now is a Bad Thing.<br>
<br>
And I suspect that Steven C is probably the right person to know about<br>
wrangling precedence and existing standards.<br>
<br>
-- E<br>
<br>
<br>
</span><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>
On Sep 5, 2016, at 12:30 AM, Jacob Bandes-Storch <<a href="mailto:jtbandes@gmail.com" target="_blank">jtbandes@gmail.com</a><br></span><span>
<mailto:<a href="mailto:jtbandes@gmail.com" target="_blank">jtbandes@gmail.com</a>>> wrote:<br>
<br>
Now you've gotten me thinking about precedence of other operators too.<br>
<br>
Since ?? is prone to causing confusion in either direction (cf. your<br>
example and my example), it could be put in its own group whose<br>
relation to the numeric operators is intentionally undefined (thus<br>
requiring parens).<br>
<br>
I don't know about other folks, but I'll certainly get confused if &<br>
and | and ^ are mixed. What if we removed their relation to each<br>
other (requiring parens when mixing them)?<br>
<br>
<proposed-precedence.png><br>
<br>
For comparison (ha), here's what we have today:<br>
<br>
<current-precedence.png><br>
<br>
Jacob<br>
<br>
On Sat, Sep 3, 2016 at 10:20 PM, Erica Sadun <<a href="mailto:erica@ericasadun.com" target="_blank">erica@ericasadun.com</a><br></span>
<mailto:<a href="mailto:erica@ericasadun.com" target="_blank">erica@ericasadun.com</a>>> wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>
On Sep 3, 2016, at 10:15 PM, Jacob Bandes-Storch<br></span><span>
<<a href="mailto:jtbandes@gmail.com" target="_blank">jtbandes@gmail.com</a> <mailto:<a href="mailto:jtbandes@gmail.com" target="_blank">jtbandes@gmail.com</a>>> wrote:<br>
<br>
Perhaps-conversely, what should this code do?<br>
<br>
let nextIndex = foundIndex ?? lastIndex + 1<br>
<br>
Jacob<br>
</span></blockquote><span>
<br>
It's a good counter example. And there's no optional-associative<br>
option.<br>
<br>
-- E<br>
<br>
</span><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>
<br>
On Sat, Sep 3, 2016 at 9:05 PM, Erica Sadun via swift-evolution<br></span>
<<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> <mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>>><div><div><br>
wrote:<br>
<br>
Given: `let x = Optional(3)` then<br>
<br>
`let y = 5 + x ?? 2` will not compile<br>
<br>
but<br>
<br>
`let y = 5 + (x ?? 2)` will.<br>
<br>
<br>
Should NilCoalescingPrecedence be raised? The current<br>
operator precedence chain is:<br>
<br>
BitwiseShiftPrecedence > MultiplicationPrecedence ><br>
AdditionPrecedence > RangeFormationPrecedence ><br>
CastingPrecedence > NilCoalescingPrecedence ><br>
ComparisonPrecedence > LogicalConjunctionPrecedence ><br>
LogicalDisjunctionPrecedence > TernaryPrecedence ><br>
AssignmentPrecedence > FunctionArrowPrecedence > [nothing]<br>
<br>
<br>
It seems to me that `NilCoalescingPrecedence` should<br>
probably be higher than `MultiplicationPrecedence` and<br>
possibly higher `BitwiseShiftPrecedence` as its job is to<br>
produce an unwrapped value that can then be operated upon.<br>
<br>
I think CastingPrecedence should be even higher because<br>
<br>
`expression as? T ?? fallback value`<br>
<br>
should be parsed as<br>
<br>
`(expression as? T) ?? (fallback value)`<br>
<br>
<br>
I apologize profusely because I know this is beyond last minute,<br>
<br>
-- E<br>
<br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br></div></div>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> <mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a>><br>
<br>
<br>
</blockquote>
<br>
<br>
</blockquote>
<br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> <mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><span><br>
<<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a>><br>
<br>
<br>
<br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br>
</span></blockquote>
</blockquote></div></div></div>