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

Kevin Lundberg kevin at klundberg.com
Tue May 17 23:39:08 CDT 2016

On 5/18/2016 12:03 AM, Brent Royal-Gordon via swift-evolution wrote:
> I'm in favor, with one small concern:
>> Then, the protocol author is responsible for providing a generic global trampoline operator that is constrained by the protocol type and delegates to the static operator on that type:
>> 	func == <T: Equatable>(lhs: T, rhs: T) -> Bool {
>> 	  return T.==(lhs, rhs)
>> 	}
> This trampoline operator, and all of the others in the proposal, appears to be 100% pure boilerplate. Could Swift generate them for us?
> (Specifically, I'm suggesting that if protocol P defines a `static func $!(args) -> ret`, Swift should automatically generate a global `func #! <T: P> (args) -> ret`, substituting `T` for any `Self`s among the parameters or return values.)
I was just about to respond to this proposal with the same feedback.
This code is purely mechanical and could be written wrong by a protocol

Additionally, I am generally +1 for the same reasons as Brent, but I
have another caveat as well:

Defining prefix and postfix functions looks like this in the proposal:

  static prefix func ++(value: inout Self) -> Self
  static postfix func ++(value: inout Self) -> Self

yet the proposal suggests calling them this way from these boilerplate

prefix func ++ <T: SomeProtocol>(value: inout T) -> T {
  return T.++(prefix: &value)
postfix func ++ <T: SomeProtocol>(value: inout T) -> T {
    return T.++(postfix: &value)

Having this mismatch between argument labels at the declaration and call
site feels strange to me, and it is inconsistent with how function
argument labels work everywhere else in the language. What if the prefix
and postfix keywords also required the functions to be disambiguated
somehow in a way that the current method naming scheme allows?

  static prefix func ++(prefix value: inout Self) -> Self
  static postfix func ++(postfix value: inout Self) -> Self

This will give a clear signal for callers to know how they should call
the function by looking at the declaration, instead of relying on a
weird edge case for these kind of operator functions. `prefix` and
`postfix` don't necessarily need to be the actual names of the arguments
that are forced by the compiler, but they should be required to be
different in the same way that you can't re-declare the same identical
function signature any other time (aside from current global
prefix/postfix functions of course).

- Kevin

More information about the swift-evolution mailing list