[swift-evolution] [Draft] Automatically deriving Equatable and Hashable for certain value types

Michael Peternell michael.peternell at gmx.at
Thu May 26 11:15:03 CDT 2016


> Am 26.05.2016 um 17:35 schrieb Matthew Johnson <matthew at anandabits.com>:
> 
> 
>> On May 26, 2016, at 10:18 AM, T.J. Usiyan via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>> +1 to a `deriving` keyword
> 
> + 1.  I like it as well.  It makes the feature opt-in, declaring conformance and requesting synthesis at the same time.  The syntactic difference from a simple conformance declaration means manual conformance can still be checked properly with no ambiguity about whether you were requesting synthesis or not.  This approach also generalizes well.
> 
> This bullet makes me uncomfortable though:
> 
>> - It is compatible with generics. E.g. `struct Shape<T> deriving Equatable` will make every `Shape<X>` equatable if `X` is equatable. But if `X` is not equatable, `Shape<X>` can be used as well. 
> 
> You should not be able to just say `struct Shape<T> deriving Equatable`.  You should have to do this:
> 
> extension Shape deriving Equatable where T: Equatable {}
> 
> Or some equivalent syntax that makes it clear that you only intend to derive equatable when T meets the stated conditions.

I agree that this might be a problem that needs some consideration. The difference in Haskell is that type declarations are usually very short, e.g.

    data Maybe a = Nothing | Just a deriving (Eq, Ord)

and to any sane reader it is obvious, that if `a` is not in `Eq`, then `Maybe a` is not in `Eq` as well. Having to write something like

    data Maybe a = Nothing | Just a deriving ({Eq where Eq a}, {Ord where Ord a})

would produce no benefit. The situation is a bit different in Swift, because type declarations are usually much larger. On the other hand, Generics are less important in Swift than they are in Haskell, so having a slightly more awkward syntax when using it in a generic way is not that bad. Maybe we could say

    struct Shape<T> deriving Eq? { ... }

and the "?" after Eq means "if possible"? To opt-in for "derive if you can" behavior? However, I would like to see an example where the "derive if you can" behavior would lead to problems / confusing language semantics. I'm not saying that there is no such example, I just cannot think of one currently. The worst that can happen is that the developer is surprised that a particular type is not equatable, even though he has "derived" an Equatable "instance". He will find out at compile time I guess, and Stackoverflow will have the answer ("swift deriving doesn't work"). But still, the question is also how obvious the requirements for a type are for `deriving Equatable` to work well.

-Michael



More information about the swift-evolution mailing list