<div dir="ltr"><div>There have been complaints on current syntax of operator declarations:</div><div><br></div><div>infix operator &lt;&gt; { associativity left precedence 100 assignment }</div><div><br></div><div>It looks like a collection of random words. Dictionary syntax would suit better here. Additionally, `assignment` has been deprecated for a long time, but not removed.</div><div><br></div><div>Many syntaxes were suggested. For example:</div><div><br></div><div>#operator(&lt;&gt;, fixity: infix, associativity: left, precedence: 100)</div><div><br></div><div>*But* Joe Groff uncovered a deeper problem. Current operators cannot be given precedence and associativity per concrete operator function.</div><div><br></div><div>Moreover, it makes more sense for operators to only allow parenthesis omission for some other operators. (C/C++ gives warnings for relying on precedence for unrelated operators.) </div><div><br></div><div>Operator declarations may lie in different modules and not know anything about each other, but they will create a conflict if their names happen to be identical.</div><div><br></div><div>The following is my attempt at solving the problem.</div><div><br></div><div>1.</div><div>All operators are aliases for functions.</div><div><br></div><div>#operator(+, name: numericAdd, fixity: infix, associativity: left)</div><div><br></div><div>func numericAdd(left: Int, _ right: Int) -&gt; Int</div><div><br></div><div>#operator(+, name: numericUnaryPlus, fixity: prefix)</div><div><br></div><div>func unaryPlus(right: Int) -&gt; Int</div><div><br></div><div>+1 + 2  // same as numericAdd(numericUnaryPlus(1), 2)</div><div><br></div><div>2.</div><div>Operators with same &quot;operator form&quot; use overloading, modified to accomodate associativity and precedence.</div><div><br></div><div>#operator(+, name: append, fixity: infix)</div><div><br></div><div>func append&lt;T&gt;(left: [T], right: T) -&gt; [T]</div><div><br></div><div>var arr = [1, 2, 3]</div>1 + 2 + 3  //=&gt; 6<div>[1, 2] + 3  //=&gt; 1 2 3</div><div>[1, 2] + 3 + 4  // error</div><div><br></div><div>Compiler must try to apply rules of both `numericAdd` and `append` in all combinations. Complexity of this should not be exponential: most branches will be cut off fast, starting from the inside.</div><div><br></div><div>In 1 + 2 + 3, `append` cannot be applied both to 1+2 and to 2+3, so we are left with `numericAdd`.</div><div>In [1,2] + 3 + 4, `numericAdd` cannot be applied to [1,2] + 3, and `append` cannot be applied to 3 + 4. But if we assume `append` and `numericAdd`, then no precedence rule is defined between `numericAdd` and `append`.</div><div><br></div><div>Overall, algorithm for compiler is to be developed.</div><div><br></div><div>3.</div><div>Operators can define precedence (omission of parentheses), only compared to other specific operators.</div><div><br></div><div>#precedence(append, lessThan: numericAdd)</div><div><br></div><div>#precedence(numericAdd, equalTo: numericSubtract)</div><div><br></div><div>4.</div><div>Precedence applies to unary operators as well:</div><div><br></div><div>let v: Bool? = false</div><div>let u = !v!  // error, precedence between logicalNot and forceUnwrap is not defined</div><div><br></div><div>#precedence(forceUnwrap, greaterThan: logicalNot)</div><div><br></div><div>let u = !v!  // true</div><div><br></div><div>That said, precedence of unary operators is always higher than of any binary operator.</div><div><br></div><div>- Anton</div></div>