[swift-evolution] [Draft] Resolving operator precedence conflicts

Austin Zheng austinzheng at gmail.com
Tue Mar 8 14:33:08 CST 2016


I agree that operator syntax needs to be reworked, but I prefer that
whatever proposal ends up being accepted not abuse the word 'fixity' to
mean something it doesn't.

On Tue, Mar 8, 2016 at 12:13 PM, Антон Жилин <swift-evolution at swift.org>
wrote:

> 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
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160308/8c781c1d/attachment.html>


More information about the swift-evolution mailing list