[swift-evolution] [swift-evolution-announce] [Review] SE-0091: Improving operator requirements in protocols

Dave Abrahams dabrahams at apple.com
Fri Jun 10 19:52:19 CDT 2016

on Fri Jun 10 2016, Tony Allevato <swift-evolution at swift.org> wrote:

>> 5) Forwarding functions aren’t good for tools. Under this proposal, if I
>> write “1 + 2” and use a tool to look at which “+” it resolved to, what will
>> we see? The generic forwarding operator. Even though I could look in the
>> source and see this:
>> extension Int {
>>   static func +(lhs: Int, rhs: Int) -> Int { … }
>> }
>> and even those that’s what will get called, my tools aren’t going to
>> interpret the body of the global forwarding function for + to resolve it in
>> the obvious way.
>> *The Good Parts*
>> With all that negative, one might get the impression that I don’t like
>> operators in types. I think there are improvements here:
>> I) Writing an operator function in a type/extension of a type is far more
>> natural that writing one at global scope for the common case. Even if
>> you’re not planning on conforming to a protocol, it just feels right that
>> (say) String + String should be defined in an extension of String. It’s
>> better for tooling (which can more easily associate the operator + with the
>> String type), code organization, works with the new meaning of the
>> “private” access modifier, and simply feels like Swift.
>> II) The requirement to use “static” on the operator function requirement
>> in the protocol makes perfect sense to me. It’s a lot clearer, and
>> communicates the semantics better. I can’t recall why we didn’t do this in
>> the first place.
>> III) The goal to reduce the total number of overloads is laudable. It can
>> help type checker performance (fewer overloads == less exponential
>> behavior) and improve diagnostics (fewer candidates to display on error).
>> The key insight here is that we don’t want to consider both a generic
>> operator based on some protocol (e.g., + for Arithmetic types) *and* the
>> operator functions that are used to satisfy the corresponding requirement.
>> *An Alternative Approach*
>> Let’s accept (I) and (II). But, let’s make operator lookup always be
>> global, so that it sees all operators defined at either module scope or
>> within a type/extension of a type. This gives us the syntactic improvements
>> of the SE-0091 “immediately”, and eliminates all five of my complaints
>> above: the natural Swift thing of defining your functionality within the
>> type or an extension thereof “just works”. It’s weird in the sense that
>> operators will be the only place where we do such global lookup—finding
>> entries at both global and type scope. However, SE-0091 is introducing a
>> different weird name lookup rule, and it feels like there’s really no way
>> to avoid it: we simply don’t want normal lexical name lookup for operators
>> when they can be defined in types.
>> This approach does not (directly) give any of the type checker
>> performance/QoI improvements of (III). However, we can achieve that by
>> making the key insight of (III) 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, e.g., the Arithmetic +
>> effectively has a generic function type like this:
>> <Self: Arithmetic> (Self, Self) -> Self
>> which is basically what the forwarding functions look like in SE-0091 at a
>> type level. 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 of
>> SE-0091’s approach to (III)—but it’s more automatic.
> I like this suggestion very much, and I would support it—especially if it's
> easier to implement than the trampoline generation that I proposed for the
> same effect.

+1; I'm on board.  Thanks for doing the hard design work, Doug!


More information about the swift-evolution mailing list