<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">Am 27.04.2016 um 16:45 schrieb Dave Abrahams <<a href="mailto:dabrahams@apple.com" class="">dabrahams@apple.com</a>>:</div><br class="Apple-interchange-newline"><div class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class="Apple-interchange-newline">On Apr 27, 2016, at 2:20 AM, Thorsten Seitz <<a href="mailto:tseitz42@icloud.com" class="">tseitz42@icloud.com</a>> wrote:<br class=""><br class="">Am 27. April 2016 um 00:32 schrieb Dave Abrahams via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>>:<br class=""><br class=""><blockquote type="cite" class=""><br class="">on Tue Apr 26 2016, Tony Allevato <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""><blockquote type="cite" class="">On Sun, Apr 24, 2016 at 2:57 AM Nicola Salmoria via swift-evolution<br class=""><<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">func isEqual(to other: Self) ->Bool<br class="">func isLess(than other: Self) ->Bool<br class="">func isLessThanOrEqual(to other: Self) ->Bool<br class=""></blockquote><br class="">I'm still not sure why these are methods instead of operators.<br class=""></blockquote><br class="">I think this is an *excellent* choice, and I hope it is the first step to<br class="">completely removing operators from protocols.<br class=""><br class="">IMHO throwing operators into protocols is inconsistent and confusing. Having<br class="">regular methods and a single generic version of the operator that calls down<br class="">on the type’s methods is clearer and guarantees that generic code can avoid<br class="">ambiguities by calling the methods directly, instead of having to rely only<br class="">on heavily overloaded global operators.<br class=""><br class="">I personally disagree on this point. To me, a protocol describes a set of<br class="">requirements for a type to fulfill, which includes things other than methods.<br class="">Just as a protocol can define initializers, properties, and associated types<br class="">that a type must define in order to conform, it makes sense that a protocol<br class="">would also define which operators a conforming type must support.<br class=""><br class="">Introducing a mapping between names and operators poses a few problems:<br class=""><br class="">– IMO, they are overly verbose and add noise to the definition. This makes the<br class="">language look less clean (I'm getting visions of NSDecimalNumber).<br class="">– They expose two ways to accomplish the same thing (writing `x.isEqual(to: y)`<br class="">and `x == y`).<br class="">– Do certain operators automatically get mapped to method names with appropriate<br class="">signatures across all types, or does a conforming type still have to provide<br class="">that mapping by implementing the operators separately? If it's the latter,<br class="">that's extra work for the author of the type writing the protocol. If it's the<br class="">former, does it make sense to automatically push these operators for all types?<br class="">Should any type that has an `add` method automatically get `+` as a synonym as<br class="">well? That may not be desirable.<br class=""><br class="">I'm very supportive of the floating-point protocol proposal in general, but I<br class="">feel the arithmetic and comparison operations should be exposed by operators<br class="">alone and not by methods, where there is a suitable operator that has the<br class="">intended meaning.<br class=""></blockquote><br class="">The main reasons to route through a single generic operator<br class="">implementation are:<br class=""><br class="">* User experience; we want to cut down the number of overloads of any<br class="">operator to a manageable set, in part because they live in the global<br class="">namespace. When you look at a list of functions in the global<br class="">namespace, seeing fifty instances of `func +` is not helpful.<br class=""><br class="">* Type checker speed. Having all of these overloads around has<br class="">historically put a strain on the type checker and made compilation<br class="">slow. That may be less true today than it once was, though.<br class=""></blockquote><br class=""><br class="">I understand these arguments but do not like the ambiguity created ("which should I use: isEqual() or ==?", "Is there a semantic difference between them?").<br class=""><br class="">Therefore I would like to hear what you all think of the following suggestion (which I already suggested in this thread, but not as explicitly as now):<br class=""><br class="">protocol Equatable {<br class=""> protected func isEqual(to other: Self) -> Bool<br class="">}<br class=""><br class="">func ==<T: Equatable>(lhs: T, rhs: T) -> Bool {<br class=""> return lhs.isEqual(to: rhs)<br class="">}<br class=""><br class="">`protected` (or something else) would mean<br class="">- visible within conforming definitions<br class="">- visible within the same file, i.e. the operator definition which therefore has to be placed in the same file as the protocol declaration<br class=""><br class="">This would allow defining isEqual() in structs or classes conforming to Equatable but not make it part of the public interface of Equatable.<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">I think something like that could be possible for Swift 4, but with everything going on and WWDC approaching I am truly out of bandwidth to consider anything like that deeply at the moment.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div><br class=""></div>I understand completely and appreciate fully what you all are doing!</div><div><br class=""></div><div>Removing the methods later will be a breaking change, though, so if possible we should not add them now or at least name them with a leading underscore and introduce a convention that such methods are not really public.</div><div><br class=""></div><div>-Thorsten</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Sorry,</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">--Dave</span></div></blockquote></div><br class=""></body></html>