Interesting, I like the idea of changing how precedence is defined, but I’m 
curious how under the new scheme we would go about inserting a new operator 
unambiguously? For example:

        #precedence(•, lessThan: *)
        #precedence(~, lessThan: *)

Assuming these are defined in separate modules, how do we determine the order 
of • and ~?

On a related note, I never encounter precedence issues because I always use 
parenthesis, since I know I’ll just forget the precedence rules so it’d be a 
mistake for me to rely on them. If we’re adding operators in precedence 
hierarchies then that only makes it even harder to learn/remember, so I wonder 
if we might actually be better served by removing precedence entirely? i.e- the 
compiler would instead require the use of parenthesis to eliminate ambiguity 
like so:

        let a = 5 + 6                   // Correct, as there aren’t enough 
operators for ambiguity
        let b = 5 + 6 * 7 + 8           // Incorrect, as it relies on 
precedence to be meaningful
        let c = (5 + 6) * (7 + 8)       // Correct, as parenthesis eliminates 
ambiguity/the need for precedence

This not only eliminates the need to learn, remember and/or lookup precedence, 
but it’s clearer and avoids mistakes, and IMO it’s actually more readable 
despite the added noise.

> On 3 Apr 2016, at 10:36, Антон Жилин via swift-evolution 
> <[email protected]> wrote:
> 
> Swift 2.2 is out, and I restart discussion on syntax for custom operators. I 
> insist that this time we should focus less on linguistic aspects.
> 
> https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md
>  
> <https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md>
> 
> Introduction
> 
> Replace syntax of operator definition:
> 
> infix operator <> { precedence 100 associativity left }
> With a directive:
> 
> #operator(<>, fixity: infix, associativity: left)
> Also replace numeric definition of precedence with separate comparative 
> precedence definitions:
> 
> #precedence(+, lessThan: *)
> #precedence(+, equalTo: -)
> Swift-evolution thread: link to the discussion thread for that proposal 
> <https://lists.swift.org/pipermail/swift-evolution>
>  
> <https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md#motivation>Motivation
> 
>  
> <https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md#problems-with-numeric-definition-of-precedence>Problems
>  with numeric definition of precedence
> 
> In the beginning, operators had nice precedence values: 90, 100, 110, 120, 
> 130, 140, 150, 160.
> 
> As time went, new and new operators were introduced. Precedence could not be 
> simply changed, as this would be a breaking change. Ranges got precedence 
> 135, as got precedence 132. ?? had precedence greater than <, but less 
> thanas, so it had to be given precedence 131.
> 
> Now it is not possible to insert any custom operator between < and ??. It is 
> an inevitable consequence of current design: it will be impossible to insert 
> an operator between two existing ones at some point.
> 
>  
> <https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md#problems-with-a-single-precedence-hierarchy>Problems
>  with a single precedence hierarchy
> 
> Currently, if an operator wants to define precedence by comparison to one 
> operator, it must do so for all other operators.
> 
> In many cases, this is not wished. Example: a & b < c is a common error 
> pattern. a / b as Double is another one. C++ compilers sometimes emit 
> warnings on these. Swift does not.
> 
> The root of the problem is that precedence is defined between all operators. 
> If & had precedence defined only by comparison to other bitwise operators and 
> / – only to arithmetic operators, we would have to place parentheses in such 
> places, not get subtle bugs, and not ever have to look at the huge operator 
> precedence table.
> 
>  
> <https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md#problems-with-current-operator-definition-syntax>Problems
>  with current operator definition syntax
> 
> Some argue that current operator syntax is not consistent with other language 
> constructs. Properties of operators have dictionary semantics and should be 
> defined as such. It is a rather weak argument right now, but after reworking 
> of precedence, the new syntax will be more to place. More reasons are given 
> below.
> 
>  
> <https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md#conflicts-of-operator-definitions>Conflicts
>  of operator definitions
> 
> Consider two operator definitions in different modules.
> 
> Module A:
> 
> infix operator |> { precedence 137 associativity left }
> Module B:
> 
> infix operator |> { precedence 138 associativity left }
>  
> <https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md#proposed-solution>Proposed
>  solution
> 
>  
> <https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md#change-syntax-for-operator-definition>Change
>  syntax for operator definition
> 
> #operator(<>, fixity: infix, associativity: left)
> #operator(!, fixity: postfix)
> First parameter of #operator directive is name of the operator. Then goes 
> required parameter fixity that can be infix,prefix, or postfix. Then, for 
> infix operators, goes optional associativity parameter that can be left or 
> right.
> 
>  
> <https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md#comparative-precedence>Comparative
>  precedence
> 
> Remove precedence property from operator definitions. Instead, introduce 
> #precedence directive:
> 
> #precedence(+, lessThan: *)
> #precedence(*, equalTo: /)
> Omission of parentheses is allowed only when precedence between the two 
> operators is defined.
> 
> 1 + 2 * 3  // ok
> 1 + 2 - 3  // error!
> #precedence(-, equalTo: +)
> 1 + 2 - 3  // now ok
> Precedence equality can only be defined for operators with same associativity.
> 
>  
> <https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md#conflict-resolution>Conflict
>  resolution
> 
> Precedence rules can be added freely across modules. Ability to omit 
> parentheses around more operators will not break any code in included 
> modules. On the other hand, conflicting precedence rules result in an error:
> 
> #precedence(*, lessThan: +)  // error, previously defined `+` < `*`
> Operator definitions do nut cause conflicts, unless they are infix and one of 
> them has associativity: left, but another one has associativity: right.
> 
> #operator(!, fixity: prefix)  // ok, duplicated definitions
> #operator(<>, fixity: infix)
> #operator(<>, fixity: infix, associativity: left)  // ok, now left associative
> #operator(+, fixity: infix, associativity: right)  // error: associativity 
> conflict
> So, if two modules define a custom operator with somewhat similar semantics 
> (at least associativity), they can be used together. Prefix and postfix 
> operators can never have conflicts in definitions. If they define different 
> precedence by comparison to same operators, then, most probably, they had 
> completely different semantics, and the situation is similar to conflict of 
> functions.
> 
>  
> <https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md#detailed-design>Detailed
>  design
> 
> operator keyword and local keywords associativity, precedence, left, right 
> will be removed.
> 
> Directives with following (informal) syntax will be added:
> 
> #operator(OPERATOR_NAME, fixity: FIXITY)
> #operator(OPERATOR_NAME, fixity: infix, associativity: ASSOCIATIVITY)
> #precedence(OPERATOR_NAME, lessThan: OPERATOR_NAME)
> #precedence(OPERATOR_NAME, equalTo: OPERATOR_NAME)
>  
> <https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md#impact-on-existing-code>Impact
>  on existing code
> 
> Standard library operator declarations will need to be rewritten. Some of the 
> existing precedence rules will need to be rewritten using #precedence 
> directive.
> 
> More importantly, it needs to be discussed what operator precedence rules do 
> not need to be retained.
> 
> User defined operators will need to be rewritten as well. But precedence will 
> have to be defined by the user. Meanwhile, we can automatically insert 
> parentheses to user code where needed.
> 
>  
> <https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md#alternatives-considered>Alternatives
>  considered
> 
>  
> <https://github.com/Anton3/swift-evolution/blob/operator-precedence/proposals/NNNN-operator-precedence.md#leave-current-operator-syntax-but-change-precedence>Leave
>  current operator syntax (but change precedence)
> 
> #precedence does not make sense to be defined inside of operator definition, 
> as it describes relationship of two operators. If so, then we are left with 
> the following declaration syntax:
> 
> prefix operator ! { }
> infix operator |> { }
> infix operator <> { associativity left }
> If body of operator can only contain associativity (in some cases), then the 
> existence of body itself makes no sense.
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to