<div dir="ltr">First of all, sorry for the delay. I still hope to finish the discussion and push the proposal to review for Swift 3.0.<div>Link for newcomers:</div><div><a href="https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md">https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md</a></div><div><br></div><div>Sadly, I&#39;ve moved into the territory opposite to what I had in mind in the beginning: absense of conflict resolution.</div><div>I wanted lightweight directives, but am moving to closed precedence groups.</div><div><br></div><div>It&#39;s just IMHO, and I think I just need input on this from more people. I still have not heard anything from Core team.</div><div><br></div><div>My main question would be: maximally &quot;mergeable&quot; directives or closed declarations?</div><div><br></div><div>Now, another iteration of syntax discussion.</div>I&#39;ve created a sample of definitions of precedence operators for standard library, using precedence groups (at the end of the proposal).<div><br><div>There is no evidence that an operator could logically belong to multiple precedence groups.</div><div>Really, precedence groups are just a way of writing multiple identical operator declarations in a shorter way.</div><div><br></div><div>Precedence groups will be closed, meaning that no precedence relations can be added to them outside of their bodies.</div><div>It will make merging all standard library operators in a giant hierarchy less tempting, although possible.</div><div>Still, that would be possible. We could disallow that specifically as a future direction (only for standard library).</div><div><br></div><div>Still, new operators must be able to be added to existing precedence groups.</div><div>Extensions cannot be used, because namespaces of types and precedencegroups will not intersect.</div><div>So I have to return to declaration of operators, if noone finds a better way and if noone objects:<br></div><div><br></div><div>precedencegroup Additive {</div><div>    members(+, -)</div><div>    associativity(left)</div><div>    precedence(&gt; Comparative)</div><div>}</div><div>infix operator +</div><div>infix operator -</div><div></div><div><div>infix operator &amp;+ { precedencegroup(Additive) }</div><div><br></div><div>All operators must have precedence groups.</div><div>I thought of allowing operators to be single-operator precedence groups, but it wouldn&#39;t give any real benefits.</div><div>I also thought of allowing operators without precedence, but almost all operators will want at least `precedence(&gt;Assignment)`.</div><div><br></div><div>Now, what questions did arise from standard library operator declarations?</div></div><div><br></div><div>1. All precedence groups have a &quot;parent&quot;.</div><div>It means, all operators will want to have precedence higher than Comparative or Ternary, or, at least, Assignment.</div><div><br></div><div>2. Moreover, I could not find any case where I had to write anything other than precedence(&gt;, ...)</div><div>Of cause, I cheated, because I can control all these declarations.</div><div>Mere people will have to use `&lt;` to say that Additive, for example, should have less priority than their custom operator.</div><div><br></div><div>But... can you build a custom operator where `&lt;` will actually be needed? I have even stronger doubts on `=`.</div><div>Maybe we can even contract this feature to `parent(Comparative)` or something without losing any expressivity?</div><div><br></div><div>3. Can we allow operators to have less priority than `=`?</div><div>If yes, can you give an example of such operator?</div><div><br></div><div>4. Operators `is`, `as`, `as?`, `as!`, `?:`, `=` are not proper Swift operators.</div><div>But we can still support these tokens for consistency.</div><div>Their only appearence would be in the standard library.</div><div>Alternatively, we can hide their precedence groups and make them a special case.</div><div>It&#39;s more a question of implementation complexity.</div><div><br></div><div>5. I removed associativity from Ternary, removed BitwiseXor from bitwise hierarchy.</div><div>And made numerous other changes that probably need to be reviewed.<br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">2016-04-06 9:17 GMT+03:00 Maximilian Hünenberger <span dir="ltr">&lt;<a href="mailto:m.huenenberger@me.com" target="_blank">m.huenenberger@me.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div><span></span></div><div><span class=""><div></div><div><br></div><div><br>Am 05.04.2016 um 22:32 schrieb Антон Жилин &lt;<a href="mailto:antonyzhilin@gmail.com" target="_blank">antonyzhilin@gmail.com</a>&gt;:<br><br></div><blockquote type="cite"><div><div dir="ltr"><a href="https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md#use-precedence-groups" target="_blank">Added</a> group version, &quot;lessThan&quot; problem can be solved nicely. `&lt;`, `=`, `&gt;` signs would be allowed there.<div><br><div>&gt; <span style="font-size:12.8px">Should we allow &quot;precedence(... equalTo ...)&quot; for operators if we have precedence groups?</span></div></div><div><span style="font-size:12.8px">I think no.</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">I have a question to your group syntax.</span></div><div><span style="font-size:12.8px">Since all operators in a precedence group must have equal associativity for parsing to work and look logically (right?), wouldn&#39;t it be better to declare associativity in groups?</span></div><div><span style="font-size:12.8px">If so, then body of operator declaration won&#39;t contain anything, and we can remove it:</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">precedenceGroup Additive {</span></div><div><span style="font-size:12.8px">    associativity(left)</span></div><div><span style="font-size:12.8px">    +, -</span></div><div><span style="font-size:12.8px">}</span></div><div><span style="font-size:12.8px">infix operator +</span></div><div><span style="font-size:12.8px">infix operator -</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">Does this body of precedenceGroup look OK from syntactic PoV?</span></div></div></div></blockquote><div><br></div></span><div>Associativity in precedence groups is fine however the operators should then be grouped possibly: &quot;operators(+, -)&quot;</div><span class=""><br><blockquote type="cite"><div><div dir="ltr"><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">Now, I have another idea.</span></div><div><span style="font-size:12.8px">As operator declarations themselves don&#39;t contain anything anymore, remove operator declarations at all. We don&#39;t need to pre-declare function names, for example.</span></div><div><span style="font-size:12.8px">Next, `precedenceGroup` could be as well replaced with `precedenceLevel`, or just `precedence`, and I would not worry about additional keywords.</span></div><div><span style="font-size:12.8px">So, our example would look like this:</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">precedence Additive {</span></div><div><span style="font-size:12.8px">    associativity(left)</span></div><div><span style="font-size:12.8px">    +, -</span></div><div><span style="font-size:12.8px">}</span></div><div>precedence Multiplicative {</div><div>    associativity(left)</div><div>    *, /</div><div>}</div><div>precedence(Additive &lt; Multiplicative)</div><div><br></div><div>As a future direction, we could add extensions to precedence levels.</div><div>We could go further and replace `precedence` with `operator`, abandoning the idea of priority for prefix and postfix operators (that I honestly don&#39;t like).</div><div><br></div></div></div></blockquote><div><br></div></span><div>Regarding pre- and postfix operators: there was a separate thread which discussed exactly this. The biggest problem was that if a prefix &quot;-&quot; has lower precedence than an infix operator like &quot;^&quot; this calculation is ambiguous from a human perspective:</div><div><br></div><div>-3 ^ 3</div><div><br></div><div>&quot;-&quot; has visually the higher precedence and the result would be 9. However the actual result is -9.</div><div><br></div><div>If we have precedence on pre- and postfix operators we would break existing code. A migratory could then enforce the old precedence levels with braces. But then we can resolve existing (visual) ambiguities and &quot;mathematical incorrectness&quot; by making the precedence of prefix &quot;-&quot; higher than the current comparative operators and not declare its precedence to higher precedence operators (precedence &gt; 140)</div><div><br></div><div>Such that this expression is ambiguous to the compiler:</div><div><br></div><div>3 - -3 // also mathematically incorrect</div><div>// and should be rewritten to</div><div>3 - (-3)</div><div>// or just</div><div>3 + 3</div><span class=""><br><blockquote type="cite"><div><div dir="ltr"><div>infix operator Additive {</div>    members(+, -)<div>    associativity(left)</div><div>}</div><div>infix operator Multiplicative {</div><div>    members(*, /)</div><div>    associativity(left)</div><div>    precedence(&gt; Additive)</div><div>}</div><div><br></div><div>Some other questions:</div><div>Do we need transitive precedence propagation?</div></div></div></blockquote><div><br></div></span><div>Yes because it would be quite a pain to declare every precedence between all precedence groups:</div><div>#needed precedence declarations ~ O(#of precedence groups ^ 2)</div><span class=""><br><blockquote type="cite"><div><div dir="ltr"><div>Do we need resolution of conflicts, i.e. merging multiple definitions of same operators and groups, where possible?</div></div><div class="gmail_extra"><div class="gmail_quote"><br></div></div>
</div></blockquote><br></span></div><div>I think we shouldn&#39;t define operators in a precedence group because if we want to have an operator in two different groups then we have two operator definitions which can result in a conflict.</div><div>I&#39;m not sure if we need the same operator in different groups. Therefore I&#39;d suggest to declare all standard library operators in this form in order to see if we need this.</div><div><br></div><div>So my current syntax suggestion is:</div><div><br></div><div>infix operator + { <span style="background-color:rgba(255,255,255,0)">associativity(left) }</span></div><div>prefix operator -</div><div>infix operator &amp;&amp; { <span style="background-color:rgba(255,255,255,0)">associativity(left) }</span></div><div><br></div><div>infix precedenceGroup Additive {</div><div>        associativity(left)</div><div>        members(+)</div><div>}</div><div><br></div><div><div><span style="background-color:rgba(255,255,255,0)">infix precedenceGroup Logical {</span></div><div><span style="background-color:rgba(255,255,255,0)">        associativity(left)</span></div><div><span style="background-color:rgba(255,255,255,0)">        members(&amp;&amp;)</span></div><div><span style="background-color:rgba(255,255,255,0)">}</span></div></div><div><span style="background-color:rgba(255,255,255,0)"><br></span></div><div><span style="background-color:rgba(255,255,255,0)">prefix precedenceGroup Sign {</span></div><div><span style="background-color:rgba(255,255,255,0)">        members(-)</span></div><div><span style="background-color:rgba(255,255,255,0)">}</span></div><div><span style="background-color:rgba(255,255,255,0)"><br></span></div><div><span style="background-color:rgba(255,255,255,0)">precedence(Additive &gt; Logical)</span></div><div>precedence(Sign &gt; Logical)</div><div><br></div><div><span style="background-color:rgba(255,255,255,0)">// warning: duplicate precedence declarations</span></div><div><span style="background-color:rgba(255,255,255,0)">precedence(Logical &lt; Additive)</span></div><div><span style="background-color:rgba(255,255,255,0)"><br></span></div><div>--------</div><div><br></div><div>I declare associativity in operator declarations and precedence group declarations since it lets the compiler check whether the &quot;members&quot; have the right associativity.</div><div><br></div><div>Best regards</div><span class="HOEnZb"><font color="#888888"><div>- Maximilian </div></font></span></div></blockquote></div><br></div>