[swift-evolution] [swift-evolution-announce] [Review #2] SE-0091: Improving operator requirements in protocols
jordan_rose at apple.com
Tue Jul 12 12:35:12 CDT 2016
[Proposal: https://github.com/apple/swift-evolution/blob/master/proposals/0091-improving-operators-in-protocols.md ]
I definitely think this is an improvement over the last version! Nice work, Tony and Doug.
I am a little confused about the implementation, though. The proposal says this:
> Instead, Swift should always perform operator lookup universally such that it sees all operators defined at either module scope or within a type/extension of a type. This gives us the syntactic improvements immediately and the natural Swift thing of defining your functionality within the type or an extension thereof just works.
and then later says
> Therefore, we can achieve the performance improvements by making that insight part of the semantic model: when we find all operators, we also find the operators in the protocols themselves. The operators in the protocols are naturally generic.
> Then, we say that we do not consider an operator function if it implements a protocol requirement, because the requirement is a generalization of all of the operator functions that satisfy that requirement. With this rule, we’re effectively getting the same effects as if users had declared trampoline operators, but it's automatic.
How do we know if an operator function implements a protocol requirement? What happens when an operator function implements a protocol requirement, but is also more general than that? And if we do find the implementation in the protocol, what conformance do we use to invoke the function when the types involved aren’t all 'Self'?
I still prefer the rule that says we perform lookup into the left type and the right type, then fall back to top-level scope for backwards compatibility.
Separately from the lookup rules, I’m still unhappy with the class problem. The proposal states this:
> We expect classes to implement the static operators in the protocol using `class` methods instead of `static` methods, which allows subclases to override them.
However, if lookup only finds the method in the protocol, it’s unclear whether this will call a conforming class's method, a static type’s method, or a dynamic type’s method; if it’s not the last, it’s hardly an “override”. I maintain that this is the wrong behavior for any class hierarchy that does include heterogeneous operations, including "assignment operators, operators for chaining tasks, DSLs for constraint systems, etc” (me, from last time).
More from last time:
>> - for class types, regardless of whether one is a base of the other or both share a common third base type, neither static nor instance methods completely solve the problem and won't until/unless Swift supports multiple dispatch, and the proposed behavior is not a regression in those cases
> I guess I’m not convinced of the chain of reasoning here. “Multi-method dispatch is the most correct way to solve the problem” is fine; “therefore, anything short of that isn’t worth doing” is where I get stuck. Instance methods partially solve the problem, and it’s possible (again, no data on hand) that they solve the problem in the majority of cases.
> (It’s also possible that the prevalence of OO has made people prefer operators that can be dispatched based on the left-hand side, so I guess I’d want to go look at, e.g. Haskell and Perl to see what operators don’t fit in that bucket.)
> I guess I’d summarize my stance as “this proposal enshrines our current problems with operator semantics in order to improve consistency in the syntax” (with “enshrines” meaning “makes harder to change later”), and that doesn’t seem like a good enough reason to change from what we have now.
…and I have to say I still feel that way. It’s not clear how much of a performance win we’ll get, and it’s not clear these are the right semantics, and it is clear that operators interact poorly with classes.
P.S. The proposal also has this line:
> non-static operator method syntax be deprecated in Swift 2 and removed in Swift 3
which should be updated in one way or another.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the swift-evolution