<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"></blockquote>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 ^.<br><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5"><div class="gmail_quote"><div dir="ltr">On Thu, Sep 8, 2016 at 04:08 Pyry Jahkola <<a href="mailto:pyry.jahkola@iki.fi" target="_blank">pyry.jahkola@iki.fi</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>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.</div><div><br></div><div>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.</div><div><br></div><div>Like Wux, I also don't think we have any reason to adjust the precedence of `??` from what it is.</div><div><br></div><div>* * *</div><div><br></div><div>But then, I also think we should do something to our bitwise ops:</div><div><br></div><div></div></div><div style="word-wrap:break-word"><div><blockquote type="cite"><div>On 08 Sep 2016, at 09:58, Xiaodi Wu via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br><div><div style="font-family:Helvetica;font-size:13px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-size:12.8px">You and I seem to agree that `</span><span style="font-size:12.8px">let i = 4 << 1 + 3` is rather reasonable.</span></div></div></blockquote><div><br></div></div></div><div style="word-wrap:break-word"><div><div>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.</div></div></div><div style="word-wrap:break-word"><div><br><blockquote type="cite"><div><div style="font-family:Helvetica;font-size:13px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-size:12.8px">I am not sure how one can make an unintended error either reading or writing this line of code[*].</span></div><div style="font-family:Helvetica;font-size:13px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-size:12.8px"><br></span></div><div style="font-family:Helvetica;font-size:13px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-size:12.8px">[*] 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.</span></div></div></blockquote></div></div><div style="word-wrap:break-word"><div></div><br>
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.<div><br></div><div>The key differences to C that I think will cause confusion in Swift are:</div><div><br></div><div>A) Unlike C, Swift defines `<<` and `>>` with the highest precedence.</div><div>B) Unlike C, Swift defines `&` at multiplication precedence (`*` etc.).</div><div>C) Unlike C, Swift defines both `^` and `|` at equal precedence to each other, and that is the precedence of addition (`+` etc.).</div><div><div><br></div><div>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:</div></div><div><br></div><div><table cellspacing="0" cellpadding="0" style="border-collapse:collapse">
<tbody>
<tr>
<td valign="top" style="width:150.0px;height:11.0px;background-color:#bec0bf;border-style:solid;border-width:1.0px 1.0px 1.0px 1.0px;border-color:#000000 #000000 #000000 #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo"><b>Infix operators in C</b></font></div>
</td>
<td valign="top" style="width:241.0px;height:11.0px;background-color:#bec0bf;border-style:solid;border-width:1.0px 1.0px 1.0px 1.0px;border-color:#000000 #000000 #000000 #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo"><b>In Swift 3</b></font></div>
</td>
</tr>
<tr>
<td valign="top" style="width:151.0px;height:10.0px;border-style:solid;border-width:1.0px 0.0px 0.0px 1.0px;border-color:#000000 transparent transparent #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#7f7f7f" style="font-size:10px;line-height:normal;font-family:Menlo;color:rgb(127,127,127)">// skipping unary ops etc</font></div>
</td>
<td valign="top" style="width:241.0px;height:10.0px;border-style:solid;border-width:1.0px 1.0px 0.0px 0.0px;border-color:#000000 #000000 transparent transparent;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;font-size:12px;line-height:normal;min-height:14px"><br></div>
</td>
</tr>
<tr>
<td valign="top" style="width:151.0px;height:11.0px;border-style:solid;border-width:0.0px 0.0px 0.0px 1.0px;border-color:transparent transparent transparent #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">* / %</font></div>
</td>
<td valign="top" style="width:241.0px;height:11.0px;border-style:solid;border-width:0.0px 1.0px 0.0px 0.0px;border-color:transparent #000000 transparent transparent;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#cf232b" style="font-size:10px;line-height:normal;font-family:Menlo;color:rgb(207,35,43)"><b> << >> // (!)</b></font></div>
</td>
</tr>
<tr>
<td valign="top" style="width:151.0px;height:11.0px;border-style:solid;border-width:0.0px 0.0px 0.0px 1.0px;border-color:transparent transparent transparent #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">+ -</font></div>
</td>
<td valign="top" style="width:241.0px;height:11.0px;border-style:solid;border-width:0.0px 1.0px 0.0px 0.0px;border-color:transparent #000000 transparent transparent;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo"> * &* / % </font><font face="Menlo" color="#cf232b" style="font-size:10px;line-height:normal;font-family:Menlo;color:rgb(207,35,43)"><b>& // (!)</b></font></div>
</td>
</tr>
<tr>
<td valign="top" style="width:151.0px;height:11.0px;border-style:solid;border-width:0.0px 0.0px 0.0px 1.0px;border-color:transparent transparent transparent #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo"><< >></font></div>
</td>
<td valign="top" style="width:241.0px;height:11.0px;border-style:solid;border-width:0.0px 1.0px 0.0px 0.0px;border-color:transparent #000000 transparent transparent;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo"> + &+ - &- </font><font face="Menlo" color="#cf232b" style="font-size:10px;line-height:normal;font-family:Menlo;color:rgb(207,35,43)"><b>| ^ // (!)</b></font></div>
</td>
</tr>
<tr>
<td valign="top" style="width:151.0px;height:11.0px;border-style:solid;border-width:0.0px 0.0px 0.0px 1.0px;border-color:transparent transparent transparent #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">< <= > >=</font></div>
</td>
<td valign="top" style="width:241.0px;height:11.0px;border-style:solid;border-width:0.0px 1.0px 0.0px 0.0px;border-color:transparent #000000 transparent transparent;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">... ..<</font></div>
</td>
</tr>
<tr>
<td valign="top" style="width:151.0px;height:11.0px;border-style:solid;border-width:0.0px 0.0px 0.0px 1.0px;border-color:transparent transparent transparent #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">== !=</font></div>
</td>
<td valign="top" style="width:241.0px;height:11.0px;border-style:solid;border-width:0.0px 1.0px 0.0px 0.0px;border-color:transparent #000000 transparent transparent;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">as as? is</font></div>
</td>
</tr>
<tr>
<td valign="top" style="width:151.0px;height:11.0px;border-style:solid;border-width:0.0px 0.0px 0.0px 1.0px;border-color:transparent transparent transparent #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">&</font></div>
</td>
<td valign="top" style="width:241.0px;height:11.0px;border-style:solid;border-width:0.0px 1.0px 0.0px 0.0px;border-color:transparent #000000 transparent transparent;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">??</font></div>
</td>
</tr>
<tr>
<td valign="top" style="width:151.0px;height:11.0px;border-style:solid;border-width:0.0px 0.0px 0.0px 1.0px;border-color:transparent transparent transparent #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">^</font></div>
</td>
<td valign="top" style="width:241.0px;height:11.0px;border-style:solid;border-width:0.0px 1.0px 0.0px 0.0px;border-color:transparent #000000 transparent transparent;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">< <= > >= == != === !== ~=</font></div>
</td>
</tr>
<tr>
<td valign="top" style="width:151.0px;height:11.0px;border-style:solid;border-width:0.0px 0.0px 0.0px 1.0px;border-color:transparent transparent transparent #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">|</font></div>
</td>
<td valign="top" style="width:241.0px;height:11.0px;border-style:solid;border-width:0.0px 1.0px 0.0px 0.0px;border-color:transparent #000000 transparent transparent;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">&&</font></div>
</td>
</tr>
<tr>
<td valign="top" style="width:151.0px;height:11.0px;border-style:solid;border-width:0.0px 0.0px 0.0px 1.0px;border-color:transparent transparent transparent #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">&&</font></div>
</td>
<td valign="top" style="width:241.0px;height:11.0px;border-style:solid;border-width:0.0px 1.0px 0.0px 0.0px;border-color:transparent #000000 transparent transparent;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">||</font></div>
</td>
</tr>
<tr>
<td valign="top" style="width:151.0px;height:11.0px;border-style:solid;border-width:0.0px 0.0px 0.0px 1.0px;border-color:transparent transparent transparent #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">||</font></div>
</td>
<td valign="top" style="width:241.0px;height:11.0px;border-style:solid;border-width:0.0px 1.0px 0.0px 0.0px;border-color:transparent #000000 transparent transparent;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#7f7f7f" style="font-size:10px;line-height:normal;font-family:Menlo;color:rgb(127,127,127)">(default precedence diverges here)</font></div>
</td>
</tr>
<tr>
<td valign="top" style="width:151.0px;height:11.0px;border-style:solid;border-width:0.0px 0.0px 0.0px 1.0px;border-color:transparent transparent transparent #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">?:</font></div>
</td>
<td valign="top" style="width:241.0px;height:11.0px;border-style:solid;border-width:0.0px 1.0px 0.0px 0.0px;border-color:transparent #000000 transparent transparent;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">?:</font></div>
</td>
</tr>
<tr>
<td valign="top" style="width:151.0px;height:11.0px;border-style:solid;border-width:0.0px 0.0px 0.0px 1.0px;border-color:transparent transparent transparent #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">= @= </font><font face="Menlo" color="#7f7f7f" style="font-size:10px;line-height:normal;font-family:Menlo;color:rgb(127,127,127)">// for various `@`</font></div>
</td>
<td valign="top" style="width:241.0px;height:11.0px;border-style:solid;border-width:0.0px 1.0px 0.0px 0.0px;border-color:transparent #000000 transparent transparent;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">= @= </font><font face="Menlo" color="#7f7f7f" style="font-size:10px;line-height:normal;font-family:Menlo;color:rgb(127,127,127)">// for various `@`</font></div>
</td>
</tr>
<tr>
<td valign="top" style="width:151.0px;height:11.0px;border-style:solid;border-width:0.0px 0.0px 1.0px 1.0px;border-color:transparent transparent #000000 #000000;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">,</font></div>
</td>
<td valign="top" style="width:241.0px;height:11.0px;border-style:solid;border-width:0.0px 1.0px 1.0px 0.0px;border-color:transparent #000000 #000000 transparent;padding:4.0px 4.0px 4.0px 4.0px"><div style="margin:0px;text-align:center"><font face="Menlo" color="#000000" style="font-size:10px;line-height:normal;font-family:Menlo">-></font></div>
</td>
</tr>
</tbody>
</table></div><div><br></div><div>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:</div><div><br></div><div>1) Move `<font face="Menlo">|</font>` and `<font face="Menlo">^</font>` into their own parallel precedence groups named <b>BitwiseOr</b> and <b>BitwiseXor</b>, just above RangeFormation.</div><div>2) Move `<font face="Menlo">&</font>` into its own group <b>BitwiseAnd</b>, just above both BitwiseOr and BitwiseXor.</div><div>3) Move <b>BitwiseShift</b> (i.e. `<font face="Menlo"><<</font>` and `<font face="Menlo">>></font>`) just above BitwiseAnd.</div><div><br></div><div>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).</div><div><br></div><div>*) E.g. none found in <a href="https://graphics.stanford.edu/~seander/bithacks.html" target="_blank">https://graphics.stanford.<wbr>edu/~seander/bithacks.html</a>.</div><div><br></div><div>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 `<font face="Menlo">a & b + c</font>`, `<font face="Menlo">a | b + c</font>`, and `<font face="Menlo">a << b - c</font>` all compile in both C and Swift, but are parsed in exactly opposing ways.</div><div><br></div><div>The whole hierarchy I'm proposing is illustrated in the attachment below, with all changes found in the top part above RangeFormation.</div><div><br></div><div>— Pyry</div><div><br></div></div></blockquote></div></div></div></blockquote></div></div></div>