I think this is a great suggestion! One potential problem I can see (if I understood this correctly) is that modules are allowed to set up their own precedence rules for operators defined elsewhere. I think this might lead to some difficult to debug errors if a developer of one module (who is used to certain conventions) then has to work with a different, independent module (where the conventions are different). This is one area where numerical precedence weights seem to be superior as they at least refer to a common subjective coordinate system.
Maybe one should also have visibility for precedence, for instance having precedence module-internal by default? Best, — Taras > On 03 Apr 2016, at 11: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
