Equatable auto-write func == Proposal


(Daniel Tartaglia) #1

Now that Swift 3 is out the door, I’m going to float this proposal again…

Given that every value type should be equatable (rational here): https://www.andrewcbancroft.com/2015/07/01/every-swift-value-type-should-be-equatable/
And that many, if not most, value types consist of properties that are value types.
Then the language should make it easy to conform to the Equatable protocol.

In other words, if I declare my value type as Equatable, and it is exclusively composed of value types that are already equatable, then implementing the actual == function should be optional (or maybe even forbidden.)

Implementing == in such cases is tedious boilerplate that the compiler should be able to infer on its own.

Does anybody want to help me write up an official proposal?


(Robert Widmann) #2

Please be careful when wording this proposal. You want derived conformances, but don't obscure that message with the claim that every type admits a useful Equatable instance. It is most certainly not the case that every value type has a useful (read [mostly]: decidable) equality. A few counterexamples, the type of lazy streams (https://github.com/typelift/Swiftz/blob/swift-develop/Swiftz/Stream.swift#L24) requires infinite space to evaluate a useful answer. The type of functions [without a modulus of continuity] also don't admit a useful, or even canonical, equality (in Swift at least).

~Robert Widmann

2016/09/10 8:24、Daniel Tartaglia via swift-evolution <swift-evolution@swift.org> のメッセージ:

···

Now that Swift 3 is out the door, I’m going to float this proposal again…

Given that every value type should be equatable (rational here): https://www.andrewcbancroft.com/2015/07/01/every-swift-value-type-should-be-equatable/
And that many, if not most, value types consist of properties that are value types.
Then the language should make it easy to conform to the Equatable protocol.

In other words, if I declare my value type as Equatable, and it is exclusively composed of value types that are already equatable, then implementing the actual == function should be optional (or maybe even forbidden.)

Implementing == in such cases is tedious boilerplate that the compiler should be able to infer on its own.

Does anybody want to help me write up an official proposal?

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Tony Allevato) #3

I started on an early-draft proposal for something like this a while back:
https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad

Most of the discussion in the e-mail thread (I don't have time to fetch the
link right now, unfortunately) was around how implicit/explicit such
behavior should be (i.e., should there be a keyword that you have to use to
buy into the automated implementation).

Given that it's additive, it's unlikely that it would be discussed now, but
I'd like to revisit it when the time is right.

···

On Mon, Sep 12, 2016 at 8:36 AM Daniel Tartaglia via swift-evolution < swift-evolution@swift.org> wrote:

Now that Swift 3 is out the door, I’m going to float this proposal again…

Given that every value type should be equatable (rational here):
https://www.andrewcbancroft.com/2015/07/01/every-swift-value-type-should-be-equatable/
And that many, if not most, value types consist of properties that are
value types.
Then the language should make it easy to conform to the Equatable protocol.

In other words, if I declare my value type as Equatable, and it is
exclusively composed of value types that are already equatable, then
implementing the actual == function should be optional (or maybe even
forbidden.)

Implementing == in such cases is tedious boilerplate that the compiler
should be able to infer on its own.

Does anybody want to help me write up an official proposal?

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Daniel Tartaglia) #4

Good point.

The real push here is that when the programmer *does* declare a type Equatable and the op == has an obvious implementation, that the programmer shouldn’t have to manually implement it him/herself. This would apply only to types that have been declared Equatable and that consist of exclusively properties which have all also been declared Equatable.

This would work much like the Haskell Eq class.

···

On Sep 12, 2016, at 12:03 PM, Robert Widmann <devteam.codafi@gmail.com> wrote:

Please be careful when wording this proposal. You want derived conformances, but don't obscure that message with the claim that every type admits a useful Equatable instance. It is most certainly not the case that every value type has a useful (read [mostly]: decidable) equality. A few counterexamples, the type of lazy streams (https://github.com/typelift/Swiftz/blob/swift-develop/Swiftz/Stream.swift#L24) requires infinite space to evaluate a useful answer. The type of functions [without a modulus of continuity] also don't admit a useful, or even canonical, equality (in Swift at least).

~Robert Widmann

2016/09/10 8:24、Daniel Tartaglia via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> のメッセージ:

Now that Swift 3 is out the door, I’m going to float this proposal again…

Given that every value type should be equatable (rational here): https://www.andrewcbancroft.com/2015/07/01/every-swift-value-type-should-be-equatable/
And that many, if not most, value types consist of properties that are value types.
Then the language should make it easy to conform to the Equatable protocol.

In other words, if I declare my value type as Equatable, and it is exclusively composed of value types that are already equatable, then implementing the actual == function should be optional (or maybe even forbidden.)

Implementing == in such cases is tedious boilerplate that the compiler should be able to infer on its own.

Does anybody want to help me write up an official proposal?


(Mark Sands) #5

I'm very interested in this moving forward. Is the swift team still holding
off on reviewing additive changes?

···

On Mon, Sep 12, 2016 at 10:43 AM, Tony Allevato via swift-evolution < swift-evolution@swift.org> wrote:

I started on an early-draft proposal for something like this a while back:
https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad

Most of the discussion in the e-mail thread (I don't have time to fetch
the link right now, unfortunately) was around how implicit/explicit such
behavior should be (i.e., should there be a keyword that you have to use to
buy into the automated implementation).

Given that it's additive, it's unlikely that it would be discussed now,
but I'd like to revisit it when the time is right.

On Mon, Sep 12, 2016 at 8:36 AM Daniel Tartaglia via swift-evolution < > swift-evolution@swift.org> wrote:

Now that Swift 3 is out the door, I’m going to float this proposal again…

Given that every value type should be equatable (rational here):
https://www.andrewcbancroft.com/2015/07/01/every-swift-
value-type-should-be-equatable/
And that many, if not most, value types consist of properties that are
value types.
Then the language should make it easy to conform to the Equatable
protocol.

In other words, if I declare my value type as Equatable, and it is
exclusively composed of value types that are already equatable, then
implementing the actual == function should be optional (or maybe even
forbidden.)

Implementing == in such cases is tedious boilerplate that the compiler
should be able to infer on its own.

Does anybody want to help me write up an official proposal?

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Chris Lattner) #6

Yep, we’re still focused on finishing Swift 3 and moving on to Swift 4 stage 1, as described here:
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160725/025676.html

-Chris

···

On Sep 13, 2016, at 2:11 PM, Mark Sands via swift-evolution <swift-evolution@swift.org> wrote:

I'm very interested in this moving forward. Is the swift team still holding off on reviewing additive changes?


(Jerome Duquennoy) #7

Hi guys,

It would be awesome if with this evolution, we could also auto-write equality operators for enum with equatable payloads.

Today, considering this enum

enum SimpleEnum {
  case case1
  case case2
}

the condition SimpleEnum.case1 == SimpleEnum.case1 compiles and return true.

But if the enum has a payload

enum EnumWithPayload {
  case integer(value: Int)
  case float(value: Float)
}

the condition EnumWithPayload.integer(value: 1) == EnumWithPayload.integer(value: 1) does not compile: operator == does not exist for that type.

Hand-writing this missing equality operator turns out to be pretty fastidious and error prone, notably because you might prefer to not use a “default” case, to take advantage of the completeness check of the compiler.
So you have to write n * (n-1) cases and that can be a lot of cases !

Jerome

···

Good point.

The real push here is that when the programmer *does* declare a type Equatable and the op == has an obvious implementation, that the programmer shouldn’t have to manually implement it him/herself. This would apply only to types that have been declared Equatable and that consist of exclusively properties which have all also been declared Equatable.

This would work much like the Haskell Eq class.

> On Sep 12, 2016, at 12:03 PM, Robert Widmann<devteam.codafi at gmail.com>wrote:
>
> Please be careful when wording this proposal. You want derived conformances, but don't obscure that message with the claim that every type admits a useful Equatable instance. It is most certainly not the case that every value type has a useful (read [mostly]: decidable) equality. A few counterexamples, the type of lazy streams (https://github.com/typelift/Swiftz/blob/swift-develop/Swiftz/Stream.swift#L24) requires infinite space to evaluate a useful answer. The type of functions [without a modulus of continuity] also don't admit a useful, or even canonical, equality (in Swift at least).
>
> ~Robert Widmann
>
> 2016/09/10 8:24、Daniel Tartaglia via swift-evolution<swift-evolution at swift.org<mailto:swift-evolution at swift.org>>のメッセージ:
>
> > Now that Swift 3 is out the door, I’m going to float this proposal again…
> >
> > Given that every value type should be equatable (rational here): https://www.andrewcbancroft.com/2015/07/01/every-swift-value-type-should-be-equatable/
> > And that many, if not most, value types consist of properties that are value types.
> > Then the language should make it easy to conform to the Equatable protocol.
> >
> > In other words, if I declare my value type as Equatable, and it is exclusively composed of value types that are already equatable, then implementing the actual == function should be optional (or maybe even forbidden.)
> >
> > Implementing == in such cases is tedious boilerplate that the compiler should be able to infer on its own.
> >
> > Does anybody want to help me write up an official proposal?


(Francisco Costa) #8

+1 for making enums with payloads Equatable by default. Right now this
requires lots of copy-paste boiler plate that can easily result in bugs.

As for the general struct case, I think there could be a default
implementation but we should be able to overwrite `==` if we need to.
Doesn't seem sensible to me comparing several inner objects and arrays if a
single `uuid` would suffice.

Francisco

···

On Mon, Sep 19, 2016 at 3:15 PM, Jérôme Duquennoy via swift-evolution < swift-evolution@swift.org> wrote:

Hi guys,

It would be awesome if with this evolution, we could also auto-write
equality operators for enum with equatable payloads.

Today, considering this enum

enum SimpleEnum {
  case case1
  case case2
}

the condition SimpleEnum.case1 == SimpleEnum.case1 compiles and return
true.

But if the enum has a payload

enum EnumWithPayload {
  case integer(value: Int)
  case float(value: Float)
}

the condition EnumWithPayload.integer(value: 1) == EnumWithPayload.integer(value:
1) does not compile: operator == does not exist for that type.

Hand-writing this missing equality operator turns out to be pretty
fastidious and error prone, notably because you might prefer to not use a
“default” case, to take advantage of the completeness check of the compiler.
So you have to write n * (n-1) cases and that can be a lot of cases !

Jerome

> Good point.
>
> The real push here is that when the programmer *does* declare a type
Equatable and the op == has an obvious implementation, that the programmer
shouldn’t have to manually implement it him/herself. This would apply only
to types that have been declared Equatable and that consist of exclusively
properties which have all also been declared Equatable.
>
> This would work much like the Haskell Eq class.
>
> > On Sep 12, 2016, at 12:03 PM, Robert Widmann<devteam.codafi at > gmail.com>wrote:
> >
> > Please be careful when wording this proposal. You want derived
conformances, but don't obscure that message with the claim that every type
admits a useful Equatable instance. It is most certainly not the case that
every value type has a useful (read [mostly]: decidable) equality. A few
counterexamples, the type of lazy streams (https://github.com/typelift/
Swiftz/blob/swift-develop/Swiftz/Stream.swift#L24<https:
//github.com/typelift/Swiftz/blob/swift-develop/Swiftz/Stream.swift#L24>)
requires infinite space to evaluate a useful answer. The type of functions
[without a modulus of continuity] also don't admit a useful, or even
canonical, equality (in Swift at least).
> >
> > ~Robert Widmann
> >
> > 2016/09/10 8:24、Daniel Tartaglia via swift-evolution<swift-evolution
at swift.org<mailto:swift-evolution at swift.org>>のメッセージ:
> >
> > > Now that Swift 3 is out the door, I’m going to float this proposal
again…
> > >
> > > Given that every value type should be equatable (rational here):
https://www.andrewcbancroft.com/2015/07/01/every-swift-
value-type-should-be-equatable/<https://www.andrewcbancroft.com/2015/07/
01/every-swift-value-type-should-be-equatable/>
> > > And that many, if not most, value types consist of properties that
are value types.
> > > Then the language should make it easy to conform to the Equatable
protocol.
> > >
> > > In other words, if I declare my value type as Equatable, and it is
exclusively composed of value types that are already equatable, then
implementing the actual == function should be optional (or maybe even
forbidden.)
> > >
> > > Implementing == in such cases is tedious boilerplate that the
compiler should be able to infer on its own.
> > >
> > > Does anybody want to help me write up an official proposal?
>
>
>

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Martin Waitz) #9

Hi,

+1 for making enums with payloads Equatable by default. Right now this
requires lots of copy-paste boiler plate that can easily result in
bugs.

Of course, making structs and enums Equatable should be much easier (the same is true for e.g. Hashable).
However, I still think Protocol conformance should be something which is specified explicitly.

When we improve support for generics we might be able to provide a default implementation for those cases where all fields are already Equatable/Hashable.
Then, making your struct conform to Equatable would be easy:

     extension MyStruct: Equatable {}

···

Am 2016-09-26 12:53, schrieb Francisco Costa via swift-evolution:

--
Martin