[swift-evolution-announce] [Review] SE-0067: Enhanced Floating Point Protocols


(Thorsten Seitz) #1

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.

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`).
– 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.

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.

The main reasons to route through a single generic operator
implementation are:

* User experience; we want to cut down the number of overloads of any
operator to a manageable set, in part because they live in the global
namespace. When you look at a list of functions in the global
namespace, seeing fifty instances of `func +` is not helpful.

* Type checker speed. Having all of these overloads around has
historically put a strain on the type checker and made compilation
slow. That may be less true today than it once was, though.

I understand these arguments but do not like the ambiguity created ("which should I use: isEqual() or ==?", "Is there a semantic difference between them?").

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):

protocol Equatable {
  protected func isEqual(to other: Self) -> Bool
}

func ==<T: Equatable>(lhs: T, rhs: T) -> Bool {
  return lhs.isEqual(to: rhs)
}

`protected` (or something else) would mean
- visible within conforming definitions
- visible within the same file, i.e. the operator definition which therefore has to be placed in the same file as the protocol declaration

This would allow defining isEqual() in structs or classes conforming to Equatable but not make it part of the public interface of Equatable.

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.

I understand completely and appreciate fully what you all are doing!

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.

-Thorsten

···

Am 27.04.2016 um 16:45 schrieb Dave Abrahams <dabrahams@apple.com>:

On Apr 27, 2016, at 2:20 AM, Thorsten Seitz <tseitz42@icloud.com> wrote:
Am 27. April 2016 um 00:32 schrieb Dave Abrahams via swift-evolution <swift-evolution@swift.org>:

on Tue Apr 26 2016, Tony Allevato <swift-evolution@swift.org> wrote:

On Sun, Apr 24, 2016 at 2:57 AM Nicola Salmoria via swift-evolution >>>> <swift-evolution@swift.org> wrote:

Sorry,
--Dave