There have been complaints on current syntax of operator declarations:

infix operator <> { associativity left precedence 100 assignment }

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.

Many syntaxes were suggested. For example:

#operator(<>, fixity: infix, associativity: left, precedence: 100)

*But* Joe Groff uncovered a deeper problem. Current operators cannot be

given precedence and associativity per concrete operator function.

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.)

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.

The following is my attempt at solving the problem.

1.

All operators are aliases for functions.

#operator(+, name: numericAdd, fixity: infix, associativity: left)

func numericAdd(left: Int, _ right: Int) -> Int

#operator(+, name: numericUnaryPlus, fixity: prefix)

func unaryPlus(right: Int) -> Int

+1 + 2 // same as numericAdd(numericUnaryPlus(1), 2)

2.

Operators with same "operator form" use overloading, modified to accomodate

associativity and precedence.

#operator(+, name: append, fixity: infix)

func append<T>(left: [T], right: T) -> [T]

var arr = [1, 2, 3]

1 + 2 + 3 //=> 6

[1, 2] + 3 //=> 1 2 3

[1, 2] + 3 + 4 // error

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.

In 1 + 2 + 3, `append` cannot be applied both to 1+2 and to 2+3, so we are

left with `numericAdd`.

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`.

Overall, algorithm for compiler is to be developed.

3.

Operators can define precedence (omission of parentheses), only compared to

other specific operators.

#precedence(append, lessThan: numericAdd)

#precedence(numericAdd, equalTo: numericSubtract)

4.

Precedence applies to unary operators as well:

let v: Bool? = false

let u = !v! // error, precedence between logicalNot and forceUnwrap is not

defined

#precedence(forceUnwrap, greaterThan: logicalNot)

let u = !v! // true

That said, precedence of unary operators is always higher than of any

binary operator.

- Anton