> Assuming these are defined in separate modules, how do we determine the order of • and ~?
By default, priority between any two operators is undefined. If two modules don't know about each other, but the user wishes to prioritize them, then he will write: #precedence(•, lessThan: ~) If • suddenly wishes to cooperate with ~, then it will add directives: #operator(~, fixity: infix, associativity: left) #precedence(•, lessThan: ~) It doesn't matter if ~ or user have already added them: if they do not contain contradictory information, there will be no conflict. > 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? That's exactly what I'm trying to do! I propose that there should be no hierarchy. Each pair of operators will have to define priority explicitly, if they need it. I'll give an example of what I mean by "removing hierarchy": #precedence(+, lessThan: *) #precedence(*, lessThan: ^) 2 ^ 3 + 6 # error #precedence(+, lessThan: ^) 2 ^ 3 + 6 # now ok - Anton 2016-04-03 13:31 GMT+03:00 Haravikk <[email protected]>: > 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 > > 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 // ok1 + 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
