[swift-evolution] Pitch: Automatically deriving Equatable/Hashable for more value types

Tony Allevato tony.allevato at gmail.com
Fri May 5 13:33:12 CDT 2017


On Fri, May 5, 2017 at 11:07 AM Matthew Johnson <matthew at anandabits.com>
wrote:

> On May 5, 2017, at 10:45 AM, Tony Allevato via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> Thanks for your feedback, everybody!
>
>
> Thanks for continuing to drive this forward!
>
>
> I've updated the gist
> <https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad> to
> reflect what seems to be a consensus here:
>
> * Derived conformances are now opt-in (this makes the recursive case
> *much* cleaner, and the complexity involved in that section has been
> completely removed)
>
>
> Can the opt-in conformance be declared in an extension?  If so, can the
> extension be in a different module than the original declaration?  If so,
> do you intend any restrictions, such as requiring all members of the type
> declared in a different module to be public?  My initial thought is that
> this should be possible as long as all members are visible.
>

Declaring the conformance in an extension in the same module should
definitely be allowed; I believe this would currently be the only way to
support conditional conformances (such as the `Optional: Hashable where
Wrapped: Hashable` example in the updated draft), without requiring deeper
syntactic changes.

I'm less sure about conformances being added in other modules, but I'm
inclined to agree with your assessment. I could see two ways of
interpreting it:

* E/H can only be derived in an extension in an external module if all the
members are accessible (and the other conditions are met).
* E/H can be derived in an extension in an external module using only the
subset of accessible members (if the other conditions are met).

These are subtly different. The argument for the first would be "if you
want to add E/H to a type in a different module, you must *consciously*
decide which members you want to use in those computations". The argument
for the second would be "you can already make a type in a different module
conform to E/H and you'd be restricted to the accessible members there, so
let's make that path easier for users too."

The first case is probably the safer choice. I'm not sure about the
implementation difficulty of each.


> * Classes are supported now as well
>
> Please take a look at the updated version and let me know if there are any
> concerns! If folks like it, I'll prepare a pull request.
>
>
> Will the synthesis for classes dispatch through a non-final method which
> is expected to be overridden by subclasses?  You don’t explicitly state
> this but it seems implied.  If so, what if  the subclass requires a custom
> implementation?  This would require the signature of the non-final method
> to be part of the synthesis contract.
>

> Supporting non-final classes introduces enough complexity (especially when
> multiple modules are involved).  I would hate to see it get sidetracked in
> discussions regarding non-final classes and miss the Swift 4 window because
> of that.  Given the limited time left for Swift 4 it might be better to
> keep the initial proposal simpler and consider a followup in the Swift 5
> timeframe to build on the initial proposal.
>

For ==, the operator must already be "class final" or "static" regardless
of this proposal, and it can't be "overridden" as such in subclasses
because the arguments would be different (lhs and rhs would be the
subclass, not the superclass). So the compiler should be able to generate
the correct implementation for subclasses in all cases, right?

For hashValue, I think the possibilities are:

* Sub is a subclass of Super. Super conforms to Hashable and implements
non-final hashValue. The compiler can derive it for Sub and call
super.hashValue in its implementation.
* Sub is a subclass of Super. Super conforms to Hashable and implements a
final hashValue. The compiler cannot derive one for Super and would
silently not do so.
* Sub is a subclass of Super. Super does not conform to Hashable, but Sub
asks to derive it. This can either (1) not be allowed, telling the user
that they need to write it manually in this case, or (2) be allowed and use
all accessible members to compute the hashValue (including those from the
superclass).

What do Encodable/Decodable do in these situations? It seems similar
solutions there would apply here.

But after writing this all out, I'm inclined to agree that I'd rather see
structs/enums make it into Swift 4 even if it meant pushing classes to
Swift 4+x.



>
>
>
> On Fri, May 5, 2017 at 8:16 AM Nevin Brackett-Rozinsky via swift-evolution
> <swift-evolution at swift.org> wrote:
>
>> On Fri, May 5, 2017 at 1:47 AM, Xiaodi Wu via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>>> On Fri, May 5, 2017 at 12:41 AM, Brent Royal-Gordon <
>>> brent at architechies.com> wrote:
>>>
>>>> I would think only final classes could participate in this, since a
>>>> subclassable class would need to allow subclasses to override equality, and
>>>> you can't override a static `==` operator method.
>>>>
>>>
>>> I work so rarely with classes that I'm embarrassed to have to ask this
>>> question: can classes not satisfy Equatable with a `public class func ==`?
>>>
>>
>> Currently:
>>
>> class C: Equatable {
>>     class func == (lhs: C, rhs: C) -> Bool {
>>         return lhs === rhs
>>     }
>> }
>>
>> Yields an error, “Operator '==' declared in non-final class 'C' must be
>> 'final'”.
>>
>> Nevin
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> 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/20170505/b8e8b212/attachment.html>


More information about the swift-evolution mailing list