<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Wed, Apr 27, 2016 at 11:07 AM Dave Abrahams via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
on Wed Apr 27 2016, Stephen Canon &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
<br>
&gt;&gt; On Apr 27, 2016, at 1:54 PM, Dave Abrahams via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; on Tue Apr 26 2016, Chris Lattner &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt;&gt; On Apr 26, 2016, at 7:34 PM, Tony Allevato via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;<br>
&gt;&gt;&gt;&gt; Would something like this be possible? Imagine protocols defined like this:<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;  public protocol Equatable {<br>
&gt;&gt;&gt;&gt;      static func == (lhs: Self, rhs: Self) -&gt; Self<br>
&gt;&gt;&gt;&gt;  }<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; The problem is that every type that conforms to Equatable has to<br>
&gt;&gt;&gt; provide an overload of == in order to conform.  This is exactly what<br>
&gt;&gt;&gt; having named methods as requirements solves.<br></blockquote><div><br></div><div>Forgive me, but I&#39;m not following you here. How would that differ from every type that conforms to `FloatingPoint` (or `Equatable`, if we modeled it the same way) having to provide an overload of `isEqual` if a generic `==&lt;T: FloatingPoint&gt;` (or `==&lt;T: Equatable&gt;`) was implemented in terms of that named method?</div><div><br></div><div>If the issue is with class hierarchies and dynamic dispatch, the conforming class can make `==` a class method instead of a static one, and then subclasses can either (1) inherit the base class implementation if they don&#39;t need to change anything, or (2) override and extend it. Thus, `T.==(lhs, rhs)` should dynamically dispatch to the same thing `lhs.isEqual(rhs)` would (since the arguments in the protocol are of type `Self`).</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
&gt;&gt;<br>
&gt;&gt; Note that Tony is proposing to make the requirement static.  Whether<br>
&gt;&gt; it&#39;s actually called “==” or isEqual is almost immaterial, because the<br>
&gt;&gt; fact that it is static makes it less likely that anyone will try to call<br>
&gt;&gt; it directly.<br>
&gt;&gt;<br>
&gt;&gt; However, if we allowed static operators to be defined, and called using<br>
&gt;&gt; the syntax “T.==(x,y)”, as Tony has suggested, IMO it would further<br>
&gt;&gt; discourage direct use, and it would avoid growing the number of<br>
&gt;&gt; truly distinct spellings for the same operation.<br></blockquote><div><br></div><div>Exactly—and in that sense, I would argue that the choice of name isn&#39;t quite immaterial, because `==` matches the global operator name while `isEqual` is arbitrary and user-chosen. This would avoid situations where one person might implement `==` with a method named `isEqual` and another might use `isSame`.</div><div><br></div><div>Granted, we already have some places where operators duplicate functionality of named methods (like `Array` mapping `+=` to `appendContentsOf`), but this approach at least lets the author of the protocol and its types use the operator name itself as the *sole and primary* name of the function when the context is such that that makes the most sense (such as arithmetic contexts) and coming up with alternative names would be either awkward or increase potential for confusion by increasing the API surface and giving the user two ways to do the same thing (when it might not be obvious if they actually do the exact same thing).</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
&gt;&gt;<br>
&gt;&gt; That would also remove many instances of “formXXX” methods that<br>
&gt;&gt; currently cause many people discomfort.  Whether that&#39;s a win or not<br>
&gt;&gt; depends on whether you view widespread discomfort with “formXXX” as a<br>
&gt;&gt; nuisance or a beneficial forcing function for finding something better<br>
&gt;&gt; ;-)</blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
&gt;<br>
&gt; Personally I like this, but t’s not totally clear how it would extend<br>
&gt; to mutating operations.  `T.+=(x: inout T, y: T)`?<br>
<br>
Well, that looks like a mix between a decl and a use.  I presume you<br>
mean<br>
<br>
  static func +=(x: inout T, y: T)<br>
<br>
and<br>
<br>
  T.+=(&amp;x, y)<br>
<br>
That seems like the obvious answer to me.<br></blockquote><div><br></div><div>Precisely. The signature would be exactly the same as the global function, just declared static in the protocol instead of non-static. In this case, the compiler would automatically generate the global trampoline operator:</div><div><br></div><div>    func += &lt;T: TheProtocol&gt;(lhs: inout T, rhs: T) { T.+=(&amp;x, y) }</div><div><br></div><div>Users could still refer to `T.+=` directly to obtain a reference to the `(inout T, T) -&gt; Void` function, but would likely only need to do this in the context of generic algorithms, and then only in situations where the compiler needed more help inferring the argument types (if `+=` by itself didn&#39;t provide enough context).</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
&gt;<br>
&gt;<br>
&gt; – Steve<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; swift-evolution mailing list<br>
&gt; <a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br>
--<br>
Dave<br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div></div>