[swift-evolution] Universal Equatability, Hashability, and Comparability

Dave Abrahams dabrahams at apple.com
Wed Mar 9 13:43:09 CST 2016


on Tue Mar 08 2016, Brian Pratt <brian-AT-pratt.io> wrote:

> Definitely a +1 on the basics. When you get inheritance involved, does that
> complicates things a little bit?
>
> Let's say I have a subclass instance that has corresponding fields with a
> superclass instance. Is it equal to said super-class instance using just
> member-wise comparisons? Would that be problematic? 

No and yes, most of the time.

The default for classes would be to compare identity; problem solved :-).

> In Scala you'd often use a reference to an "equality contract" object
> type in order to get "transitive" equality between subclasses and
> superclasses, which definitely feels like a step backwards from the
> current protocol-driven approach.
>
> On Tue, Mar 8, 2016 at 2:54 PM, Joe Groff via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>> (starting a new thread by DaveA's request)
>>
>> There's a definition of equality that makes sense as a default for nearly
>> every type in our system:
>>
>> - Basic types like IntNN, FloatNN, String, etc. have domain-defined
>> equality,
>> - Structs and tuples can be considered equal if their corresponding fields
>> are equal,
>> - Enums can be considered equal if they carry the same, equal payload,
>> - Class references can be considered equal if they refer to the same
>> instance,
>> - Metatypes can be considered equal if they represent the same type, and
>> - Existentials can be considered equal if they carry equal values of the
>> same dynamic type.
>>
>> and similarly, reasonable hash code implementations could be synthesized
>> by applying a standard hash combine operation over the components, and a
>> default ordering  could be assigned to values of every type. I think it's
>> worth considering whether Equatable, Hashable, and/or Comparable, instead
>> of being explicit protocols, should become universal behavior like 'print',
>> with customization points to override the default behavior. If Equatable
>> and Hashable behavior were universal, that would solve many of the common
>> problems people currently have trying to work with heterogeneous
>> containers. In object-oriented frameworks, including Cocoa, Java, and .NET,
>> it is common for the root (NS)Object class to provide default equality and
>> hashing operations. There are of course some tradeoffs:
>>
>> - Universal behavior would require us to either generate code for '==',
>> 'hashValue', and/or '<' for every type, or provide sufficient reflection
>> info for a common runtime implementation to do it. The reflection-based
>> approach may be reasonable for print(), since dumping reflection info only
>> reduces the quality of the default logging behavior, but '==' and
>> 'hashValue' are more essential to proper behavior, so relying on reflection
>> might be too slow, and would be brittle when we introduce the ability to
>> drop reflection info.
>> - Type safety with '==' is important to prevent accidental '1 == "1"' type
>> comparsions, and a fully generic 'func ==<T>(x: T, y: T) -> Bool' could
>> potentially allow those sorts of mixed-type comparisons by accident.
>> Language rules that constrained when generic parameters can be resolved to
>> supertypes might help here.
>> - Function types in Swift do not provide a ready equality operation. We
>> could provide a default implementation that always returns 'false', perhaps.
>> - A Comparable ordering can be dreamt up for many types, but it's not
>> always a stable ordering, or a desired one. Many people have complained
>> that 'nil < .Some(1)' works for optionals, for instance, ordering 'nil'
>> below Some values. We could use pointer identity to order class instances
>> and types, but this wouldn't be a stable ordering across process runs. That
>> might be good enough for ordered collections like search trees, but is
>> weaker than what many people expect '<' to do.
>>
>> It's my feeling that Equatable and Hashable would make a lot of sense as
>> universal operations; I'm not so sure about Comparable.
>>
>> -Joe
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>

-- 
-Dave


More information about the swift-evolution mailing list