[swift-evolution] Equatability for enums with associated values

Slava Pestov spestov at apple.com
Fri Jan 13 16:09:15 CST 2017


> On Jan 13, 2017, at 1:15 PM, Tony Allevato via swift-evolution <swift-evolution at swift.org> wrote:
> 
> This is a request that comes up frequently; I wrote an early draft proposal for it several months ago, with it covering all value types, not just enums, and also including Hashable as well as Equatable:
> 
> https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad <https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad>
> 
> Since it's purely additive, it won't get much attention until phase 2 at the earliest, but I'd like to revisit it then. Most of the discussion before revolved around to what degree users should have to opt-in or opt-out of this functionality.

I think if someone were to implement this though, we would be happy to merge it in. The code for deriving Equatable and Hashable conformances is in these files:

lib/Sema/CodeSynthesis.cpp
lib/Sema/DerivedConformances.cpp
lib/Sema/DerivedConformanceEquatableHashable.cpp

I agree it should be opt-in though (I would also argue that even the no-payload enum behavior should be opt-in, but that ship has sailed).

> 
> Re: generics, I don't think there's anything on the roadmap that goes into such deep detail as "if every associated value of every enum case is Equatable, then X is also Equatable", and I don't think there would be a clean way to express that with the generics syntax. This would probably have to be something that's baked into the compiler to synthesize == and hashValue for types that satisfy the constraints.

The generics feature people are thinking of is conditional conformances:

extension Array : Equatable where Element == Equatable { … }

However it does not solve the problem for enums with associated values because as you said there’s no way to quantify over ‘all associated values’ in the language, and this is not planned.

Slava

> 
> 
> On Fri, Jan 13, 2017 at 12:31 PM David Sweeris via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> 
> 
> 
> Sent from my iPhone
> On Jan 13, 2017, at 13:51, Adam Shin via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> 
>> When using enums with associated values, it's often necessary to check for equality between two enum objects in some way. That can lead to boilerplate code like this:
>> 
>> enum Option {
>>     case foo(String)
>>     case bar(Int)
>> 	case zip
>> }
>> 
>> func ==(lhs: Option, rhs: Option) -> Bool {
>>     switch (lhs, rhs) {
>>     case (.foo(let a), .foo(let b)) where a == b: return true
>>     case (.bar(let a), .bar(let b)) where a == b: return true
>>     case (.zip, .zip): return true
>>     default: return false
>>     }
>> }
>> 
>> ..which results in code duplication and opens the door to potential logic errors.
>> 
>> Instead, what if enums with associated values were automatically Equatable when all their associated values were Equatable? That would remove the need for such boilerplate code.
>> 
>> The Swift language guide states that custom classes and structs don't receive a default implementation of the == operator because the compiler can't guess what "equality" means for them. However, I think this could make sense for enums. An enum case, even with associated values, seems closer to a value itself than an object with logic and state.
>> 
>> I'd be interested to hear any thoughts on this. Would this be a beneficial addition?
> 
> I think it makes more sense to come up with some syntax for reducing that kind of boilerplate code in general. In "pseudo-english", I'd write the == function as "if lhs and rhs are the same case && their associated values are the equal, return true, else return false".
> 
> What about doing something with the reflection system? Isn't that supposed to get overhauled for Swift 4? I'm not sure what the performance implications would be, though.
> 
> - Dave Sweeris 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170113/5e6b8fee/attachment.html>


More information about the swift-evolution mailing list