Hi all,
I'd like to be able to specify precedence for custom pre/postfix operators.
What's your opinion? I'll let a draft of my proposal say the rest.
I’m supportive of solving this problem, but have a few comments below:
## Motivation
Operators compose expressions. Precedence affects the result of such
composition. Prefix and postfix operators are not different from infix
operator in this regard. Without the ability to specify a precedence, users
have to rely on understanding of default precedence value and parenthesis to
work with their costume prefix and postfix operators.
For example, user might need to extend the range operator `..<` to support
a `OpenRange` type, which represent a range with only one end specified with
an integer:
prefix operator ..< {}
prefix func ..<(end: Int) -> HalfRange { // … }
The user might want the following to mean `..< (someNumber + 3)` instead of
`(..< someNumber) + 3`, but they need the ability to say `..<` has higher
precedence than `+`.
let x = ..< someNumber + 3
Keep in mind that prefix operators *must* be closely bound (without whitespace) to their operand. Your example will produce "error: unary operator cannot be separated from its operand”.
Given this, I’d strongly opposed to having:
let x = ..<someNumber + 3
parse with the unary operator less tightly bound than the binary operator it works with. Also keep in mind that unspaced binary operators cannot be juxtaposed without whitespace next to a unary operator. More specifically, this is not allowed:
let x = someNumber+..<3
you have to write it as:
let x = someNumber + ..<3
and again, I’d be pretty strongly opposed to having the unary operator bind looser than the infix operator. This example also raises the issue of what this means for a prefix unary operator the on RHS of a tighter binding binary operator.
In any case, a proposal to add precedence to unary operators should tackle these issues. If we allowed whitespace between a unary operator and its operand, that itself would introduce a different host of parsing issues that would have to be solved.
The Swift compiler will implement the updated prefix and postfix operation
declaration syntax as the following:
```
prefix-operator-declaration → prefixoperatoroperator { [precedence-clause] }
postfix-operator-declaration → prefixoperatoroperator { [precedence-clause] }
This style is consistent with our existing stuff, but I’ll observe that our existing “magic number” approach to precedence levels is pretty sad in general :-).
We’ve talked about (but never had time to design and implement) an approach where operators are defined as a partial order (lattice), and the compiler sorted out their relative precedence levels from this declarative spec.
-Chris
···
On Feb 28, 2016, at 5:25 PM, Daniel Duan via swift-evolution <swift-evolution@swift.org> wrote: