Again, +1 to Tony's analysis. In the context of numerics in particular, global functions and operators are very much "normal means," and if anything instance methods are rather "convenience." On Tue, Apr 26, 2016 at 13:36 Tony Allevato via swift-evolution < [email protected]> wrote:
> On Tue, Apr 26, 2016 at 11:29 AM Nicola Salmoria < > [email protected]> wrote: > >> On Tue, Apr 26, 2016 at 8:10 PM, Thorsten Seitz <[email protected]> >> wrote: >> >>> See inline. >>> >>> Am 26.04.2016 um 19:36 schrieb Nicola Salmoria via swift-evolution < >>> [email protected]>: >>> >>> On Tue, Apr 26, 2016 at 4:28 PM, Tony Allevato <[email protected]> >>> wrote: >>> >>>> On Sun, Apr 24, 2016 at 2:57 AM Nicola Salmoria via swift-evolution < >>>> [email protected]> wrote: >>>> >>>>> > > func isEqual(to other: Self) ->Bool >>>>> > > func isLess(than other: Self) ->Bool >>>>> > > func isLessThanOrEqual(to other: Self) ->Bool >>>>> > >>>>> > I'm still not sure why these are methods instead of operators. >>>>> >>>>> I think this is an *excellent* choice, and I hope it is the first step >>>>> to completely removing operators from protocols. >>>>> >>>>> IMHO throwing operators into protocols is inconsistent and confusing. >>>>> Having regular methods and a single generic version of the operator that >>>>> calls down on the type’s methods is clearer and guarantees that generic >>>>> code can avoid ambiguities by calling the methods directly, instead of >>>>> having to rely only on heavily overloaded global operators. >>>>> >>>> >>>> I personally disagree on this point. To me, a protocol describes a set >>>> of requirements for a type to fulfill, which includes things other than >>>> methods. Just as a protocol can define initializers, properties, and >>>> associated types that a type must define in order to conform, it makes >>>> sense that a protocol would also define which operators a conforming type >>>> must support. >>>> >>> >>> Well, I'm not sure about that. A protocol describes what a type can do, >>> so it's debatable whether a global function is within this scope. >>> >>> Operators are magically special: you can declare them inside a protocol >>> and require them to be available for conformance, even if they don't belong >>> to the type. You can't do the same thing for normal global functions, yet >>> conceptually global functions and operators are the same thing. >>> >>> >>>> Introducing a mapping between names and operators poses a few problems: >>>> >>>> – IMO, they are overly verbose and add noise to the definition. This >>>> makes the language look less clean (I'm getting visions of >>>> NSDecimalNumber). >>>> – They expose two ways to accomplish the same thing (writing >>>> `x.isEqual(to: y)` and `x == y`). >>>> >>> >>> That is my concern with this approach as well. >>> >>> >>> >>> – Do certain operators automatically get mapped to method names with >>>> appropriate signatures across all types, or does a conforming type still >>>> have to provide that mapping by implementing the operators separately? If >>>> it's the latter, that's extra work for the author of the type writing the >>>> protocol. If it's the former, does it make sense to automatically push >>>> these operators for all types? Should any type that has an `add` method >>>> automatically get `+` as a synonym as well? That may not be desirable. >>>> >>> >>> The difference at the protocol declaration is between: >>> >>> protocol Equatable { >>> func ==(lhs: Self, rhs: Self) -> Bool >>> } >>> >>> and: >>> >>> protocol Equatable { >>> func isEqual(to other: Self) -> Bool >>> } >>> >>> func ==<T: Equatable>(lhs: T, rhs: T) -> Bool { >>> return lhs.isEqual(to: rhs) >>> } >>> >>> so the latter is a bit more verbose, but arguably clearer in intent, and >>> not different from how you would define any generic global function using a >>> protocol, or from how you can define protocol extensions with default >>> implementations that take advantage of the protocol's core methods. >>> >>> >>> The problem is that it is no longer clear whether to use the method or >>> the operator to check for equality. >>> >>> Now if we had some access modifier to hide the isEqual method except for >>> overwriting it and using it within the operator, maybe some variant of >>> 'protected' (e.g. visible in implementors and the same file as the >>> protocol) then that approach would be fine. >>> >>> -Thorsten >>> >> >> Why would you want to do that? >> >> I see operators mostly as a convenience: a shortcut to express in a more >> concise way something which should also be available through normal means. >> > > Why is the operator not the "normal means"? Centuries of mathematics tell > us that "2 + 2 == 4", not "2.adding(2).isEqual(to: 4)". We should make it > easier and consistent for Swift authors to write code that conforms to > existing terms (or in this case, symbols) of art, not introduce a > completely new and arbitrary set of methods that (1) bloat public > interfaces and (2) map to the same operators anyway. > > > It could be argued that generic code might prefer, for clarity, to use >> explicit methods instead of vague global operators. >> >> The approved but still unimplemented >> >> https://github.com/apple/swift-evolution/blob/master/proposals/0042-flatten-method-types.md >> also applies here, since the isEqual member method could also be used as >> a static method for increased symmetry and clarity, i.e. instead of >> >> _ = x.isEqual(to: y) >> >> one could do >> >> _ = Equatable.isEqual(x, to: y) >> >> this could be useful in case of ambiguities. >> >> Nicola >> >> >> >>> >>> >>> >>> The difference for the conformance is between: >>> >>> extension Foo : Equatable { } >>> >>> func ==(lhs: Foo, rhs: Foo) -> Bool { >>> return <comparison> >>> } >>> >>> and: >>> >>> extension Bar : Equatable { >>> func isEqual(to: Bar) -> Bool { >>> return <comparison> >>> } >>> } >>> >>> the former way to define the conformance can be confusing to newbies. >>> The latter is straightforward and consistent with the usual way to adopt a >>> protocol. >>> >>> The == operator looks exactly the same at its use points, but the way >>> how it's implemented is different. >>> In the former case, it's many overloads of a global function, which can >>> stress the compiler's type inference and doesn't offer an obvious way to >>> disambiguate in case of ambiguities. >>> In the latter case, there is only one generic definition of ==, which >>> automatically applies to all types that conform to the protocol. >>> >>> Nicola >>> >>> >>>> I'm very supportive of the floating-point protocol proposal in general, >>>> but I feel the arithmetic and comparison operations should be exposed by >>>> operators alone and not by methods, where there is a suitable operator that >>>> has the intended meaning. >>>> >>>> >>>> >>>>> >>>>> — >>>>> Nicola >>>>> >>>>> _______________________________________________ >>>>> swift-evolution mailing list >>>>> [email protected] >>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>> >>>> >>> _______________________________________________ >>> swift-evolution mailing list >>> [email protected] >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> >>> _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
