<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Apr 7, 2016, at 1:39 PM, Антон Жилин via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">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 class="">Link for newcomers:</div><div class=""><a href="https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md" class="">https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md</a></div><div class=""><br class=""></div><div class="">Sadly, I've moved into the territory opposite to what I had in mind in the beginning: absense of conflict resolution.</div><div class="">I wanted lightweight directives, but am moving to closed precedence groups.</div><div class=""><br class=""></div><div class="">It'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></div></blockquote><div><br class=""></div><div>Hi&nbsp;Антон,</div><div><br class=""></div><div>I’m sorry for the delay, I have been out of town recently. &nbsp;I haven’t read the upstream thread so I hope this isn’t too duplicative. &nbsp;Here is my 2c:</div><div><br class=""></div><div>- I completely agree that numeric precedences are lame, it was always the “plan” that they’d be removed someday, but that obviously still hasn’t happened :-)</div><div>- I definitely agree that a partial ordering between precedences is all that we need/want, and that unspecified relations should be an error.</div><div><br class=""></div><div>That said, I feel like #operator is a major syntactic regression, both in consistency and predictability. &nbsp;We use # for two things: directives (like #if) and for expressions (#file). &nbsp;The #operator is a declaration of an operator, not an expression or a directive. &nbsp;For declarations, we consistently use a keyword, which allows contextual modifiers before them, along with a body (which is sometimes optional for certain kinds of decls). &nbsp;I feel like you’re trying to syntactically reduce the weight of something that doesn’t occur very often, which is no real win in expressiveness, and harms consistency.</div><div><br class=""></div><div>Likewise #precedence is a relationship between two operators. &nbsp;I’d suggest putting them into the body of the operator declaration.</div><div><br class=""></div><div>OTOH, the stuff inside the current operator declaration is a random series of tokens with no apparent structure. &nbsp;I think it would be reasonable to end up with something like:</div><div><br class=""></div><div>infix&nbsp;operator&nbsp;&lt;&gt;&nbsp;{</div><div>&nbsp; associativity:&nbsp;left</div><div>&nbsp; precedenceLessThan: *</div><div>&nbsp; precedenceEqualTo: -</div><div>&nbsp;}</div><div><br class=""></div><div>Or whatever. &nbsp;The rationale here is that “infix” is primal on the operator decl (and thus is outside the braces) but the rest of the stuff can be omitted, so it goes inside.</div><div><br class=""></div><div>Just in terms of the writing of the proposal, in the "Change precedence mechanism” keep in mind that swift code generally doesn’t care about the order of declarations (it doesn’t parse top down in the file like C does) so the example is a bit misleading.</div><div><br class=""></div><div>Question for you: have you considered introducing named precedence groups, and having the relationships be between those groups? &nbsp;For example, I could see something like:</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>operator group additive {}</div><div><div><span class="Apple-tab-span" style="white-space: pre;">        </span>operator group multiplicative { greaterThan: additive }</div><div class=""><div><span class="Apple-tab-span" style="white-space: pre;">        </span>operator group exponential { greaterThan: additive }</div></div><div class=""><br class=""></div><div class="">Then:</div></div><div><br class=""></div><div><div>infix&nbsp;operator + {</div><div>&nbsp; associativity:&nbsp;left</div><div>&nbsp; precedence: additive</div><div>&nbsp;}</div><div class=""><div>infix&nbsp;operator - {</div><div>&nbsp; associativity:&nbsp;left</div><div>&nbsp; precedence: additive</div><div>&nbsp;}</div></div><div class=""><br class=""></div><div class="">etc.</div></div><div><br class=""></div><div>-Chris</div><div><br class=""></div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class="">Still, new operators must be able to be added to existing precedence groups.</div><div class="">Extensions cannot be used, because namespaces of types and precedencegroups will not intersect.</div><div class="">So I have to return to declaration of operators, if noone finds a better way and if noone objects:<br class=""></div><div class=""><br class=""></div><div class="">precedencegroup Additive {</div><div class="">&nbsp; &nbsp; members(+, -)</div><div class="">&nbsp; &nbsp; associativity(left)</div><div class="">&nbsp; &nbsp; precedence(&gt; Comparative)</div><div class="">}</div><div class="">infix operator +</div><div class="">infix operator -</div><div class=""></div><div class=""><div class="">infix operator &amp;+ { precedencegroup(Additive) }</div><div class=""><br class=""></div><div class="">All operators must have precedence groups.</div><div class="">I thought of allowing operators to be single-operator precedence groups, but it wouldn't give any real benefits.</div><div class="">I also thought of allowing operators without precedence, but almost all operators will want at least `precedence(&gt;Assignment)`.</div><div class=""><br class=""></div><div class="">Now, what questions did arise from standard library operator declarations?</div></div><div class=""><br class=""></div><div class="">1. All precedence groups have a "parent".</div><div class="">It means, all operators will want to have precedence higher than Comparative or Ternary, or, at least, Assignment.</div><div class=""><br class=""></div><div class="">2. Moreover, I could not find any case where I had to write anything other than precedence(&gt;, ...)</div><div class="">Of cause, I cheated, because I can control all these declarations.</div><div class="">Mere people will have to use `&lt;` to say that Additive, for example, should have less priority than their custom operator.</div><div class=""><br class=""></div><div class="">But... can you build a custom operator where `&lt;` will actually be needed? I have even stronger doubts on `=`.</div><div class="">Maybe we can even contract this feature to `parent(Comparative)` or something without losing any expressivity?</div><div class=""><br class=""></div><div class="">3. Can we allow operators to have less priority than `=`?</div><div class="">If yes, can you give an example of such operator?</div><div class=""><br class=""></div><div class="">4. Operators `is`, `as`, `as?`, `as!`, `?:`, `=` are not proper Swift operators.</div><div class="">But we can still support these tokens for consistency.</div><div class="">Their only appearence would be in the standard library.</div><div class="">Alternatively, we can hide their precedence groups and make them a special case.</div><div class="">It's more a question of implementation complexity.</div><div class=""><br class=""></div><div class="">5. I removed associativity from Ternary, removed BitwiseXor from bitwise hierarchy.</div><div class="">And made numerous other changes that probably need to be reviewed.<br class=""></div></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">2016-04-06 9:17 GMT+03:00 Maximilian Hünenberger <span dir="ltr" class="">&lt;<a href="mailto:m.huenenberger@me.com" target="_blank" class="">m.huenenberger@me.com</a>&gt;</span>:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto" class=""><div class=""><span class=""></span></div><div class=""><span class=""><div class=""></div><div class=""><br class=""></div><div class=""><br class="">Am 05.04.2016 um 22:32 schrieb Антон Жилин &lt;<a href="mailto:antonyzhilin@gmail.com" target="_blank" class="">antonyzhilin@gmail.com</a>&gt;:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><a href="https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md#use-precedence-groups" target="_blank" class="">Added</a> group version, "lessThan" problem can be solved nicely. `&lt;`, `=`, `&gt;` signs would be allowed there.<div class=""><br class=""><div class="">&gt;&nbsp;<span style="font-size:12.8px" class="">Should we allow "precedence(... equalTo ...)" for operators if we have precedence groups?</span></div></div><div class=""><span style="font-size:12.8px" class="">I think no.</span></div><div class=""><span style="font-size:12.8px" class=""><br class=""></span></div><div class=""><span style="font-size:12.8px" class="">I have a question to your group syntax.</span></div><div class=""><span style="font-size:12.8px" class="">Since all operators in a precedence group must have equal associativity for parsing to work and look logically (right?), wouldn't it be better to declare associativity in groups?</span></div><div class=""><span style="font-size:12.8px" class="">If so, then body of operator declaration won't contain anything, and we can remove it:</span></div><div class=""><span style="font-size:12.8px" class=""><br class=""></span></div><div class=""><span style="font-size:12.8px" class="">precedenceGroup Additive {</span></div><div class=""><span style="font-size:12.8px" class="">&nbsp; &nbsp; associativity(left)</span></div><div class=""><span style="font-size:12.8px" class="">&nbsp; &nbsp; +, -</span></div><div class=""><span style="font-size:12.8px" class="">}</span></div><div class=""><span style="font-size:12.8px" class="">infix operator +</span></div><div class=""><span style="font-size:12.8px" class="">infix operator -</span></div><div class=""><span style="font-size:12.8px" class=""><br class=""></span></div><div class=""><span style="font-size:12.8px" class="">Does this body of precedenceGroup look OK from syntactic PoV?</span></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Associativity in precedence groups is fine however the operators should then be grouped possibly: "operators(+, -)"</div><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><span style="font-size:12.8px" class=""><br class=""></span></div><div class=""><span style="font-size:12.8px" class="">Now, I have another idea.</span></div><div class=""><span style="font-size:12.8px" class="">As operator declarations themselves don't contain anything anymore, remove operator declarations at all. We don't need to pre-declare function names, for example.</span></div><div class=""><span style="font-size:12.8px" class="">Next, `precedenceGroup` could be as well replaced with `precedenceLevel`, or just `precedence`, and I would not worry about additional keywords.</span></div><div class=""><span style="font-size:12.8px" class="">So, our example would look like this:</span></div><div class=""><span style="font-size:12.8px" class=""><br class=""></span></div><div class=""><span style="font-size:12.8px" class="">precedence Additive {</span></div><div class=""><span style="font-size:12.8px" class="">&nbsp; &nbsp; associativity(left)</span></div><div class=""><span style="font-size:12.8px" class="">&nbsp; &nbsp; +, -</span></div><div class=""><span style="font-size:12.8px" class="">}</span></div><div class="">precedence Multiplicative {</div><div class="">&nbsp; &nbsp; associativity(left)</div><div class="">&nbsp; &nbsp; *, /</div><div class="">}</div><div class="">precedence(Additive &lt; Multiplicative)</div><div class=""><br class=""></div><div class="">As a future direction, we could add extensions to precedence levels.</div><div class="">We could go further and replace `precedence` with `operator`, abandoning the idea of priority for prefix and postfix operators (that I honestly don't like).</div><div class=""><br class=""></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Regarding pre- and postfix operators: there was a separate thread which discussed exactly this. The biggest problem was that if a prefix "-" has lower precedence than an infix operator like "^" this calculation is ambiguous from a human perspective:</div><div class=""><br class=""></div><div class="">-3 ^ 3</div><div class=""><br class=""></div><div class="">"-" has visually the higher precedence and the result would be 9. However the actual result is -9.</div><div class=""><br class=""></div><div class="">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 "mathematical incorrectness" by making the precedence of prefix "-" higher than the current comparative operators and not declare its precedence to higher precedence operators (precedence &gt; 140)</div><div class=""><br class=""></div><div class="">Such that this expression is ambiguous to the compiler:</div><div class=""><br class=""></div><div class="">3 - -3 // also mathematically incorrect</div><div class="">// and should be rewritten to</div><div class="">3 - (-3)</div><div class="">// or just</div><div class="">3 + 3</div><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">infix operator Additive {</div>&nbsp; &nbsp; members(+, -)<div class="">&nbsp; &nbsp; associativity(left)</div><div class="">}</div><div class="">infix operator Multiplicative {</div><div class="">&nbsp; &nbsp; members(*, /)</div><div class="">&nbsp; &nbsp; associativity(left)</div><div class="">&nbsp; &nbsp; precedence(&gt; Additive)</div><div class="">}</div><div class=""><br class=""></div><div class="">Some other questions:</div><div class="">Do we need transitive precedence propagation?</div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Yes because it would be quite a pain to declare every precedence between all precedence groups:</div><div class="">#needed precedence declarations ~ O(#of precedence groups ^ 2)</div><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">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 class=""></div></div>
</div></blockquote><br class=""></span></div><div class="">I think we shouldn'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 class="">I'm not sure if we need the same operator in different groups. Therefore I'd suggest to declare all standard library operators in this form in order to see if we need this.</div><div class=""><br class=""></div><div class="">So my current syntax suggestion is:</div><div class=""><br class=""></div><div class="">infix operator + { <span style="background-color:rgba(255,255,255,0)" class="">associativity(left) }</span></div><div class="">prefix operator -</div><div class="">infix operator &amp;&amp; { <span style="background-color:rgba(255,255,255,0)" class="">associativity(left) }</span></div><div class=""><br class=""></div><div class="">infix precedenceGroup Additive {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; associativity(left)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; members(+)</div><div class="">}</div><div class=""><br class=""></div><div class=""><div class=""><span style="background-color:rgba(255,255,255,0)" class="">infix precedenceGroup Logical {</span></div><div class=""><span style="background-color:rgba(255,255,255,0)" class="">&nbsp; &nbsp; &nbsp; &nbsp; associativity(left)</span></div><div class=""><span style="background-color:rgba(255,255,255,0)" class="">&nbsp; &nbsp; &nbsp; &nbsp; members(&amp;&amp;)</span></div><div class=""><span style="background-color:rgba(255,255,255,0)" class="">}</span></div></div><div class=""><span style="background-color:rgba(255,255,255,0)" class=""><br class=""></span></div><div class=""><span style="background-color:rgba(255,255,255,0)" class="">prefix precedenceGroup Sign {</span></div><div class=""><span style="background-color:rgba(255,255,255,0)" class="">&nbsp; &nbsp; &nbsp; &nbsp; members(-)</span></div><div class=""><span style="background-color:rgba(255,255,255,0)" class="">}</span></div><div class=""><span style="background-color:rgba(255,255,255,0)" class=""><br class=""></span></div><div class=""><span style="background-color:rgba(255,255,255,0)" class="">precedence(Additive &gt; Logical)</span></div><div class="">precedence(Sign &gt; Logical)</div><div class=""><br class=""></div><div class=""><span style="background-color:rgba(255,255,255,0)" class="">// warning: duplicate precedence declarations</span></div><div class=""><span style="background-color:rgba(255,255,255,0)" class="">precedence(Logical &lt; Additive)</span></div><div class=""><span style="background-color:rgba(255,255,255,0)" class=""><br class=""></span></div><div class="">--------</div><div class=""><br class=""></div><div class="">I declare associativity in operator declarations and precedence group declarations since it lets the compiler check whether the "members" have the right associativity.</div><div class=""><br class=""></div><div class="">Best regards</div><span class="HOEnZb"><font color="#888888" class=""><div class="">- Maximilian&nbsp;</div></font></span></div></blockquote></div><br class=""></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>