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

Xiaodi Wu xiaodi.wu at gmail.com
Tue May 16 07:23:53 CDT 2017


Not in this proposal, unless something has changed. I think it's reasonable
for the first iteration of this feature to say that if you want to
customize how equality is determined, you write your own `==`.


On Tue, May 16, 2017 at 05:56 T.J. Usiyan <griotspeak at gmail.com> wrote:

> Is there any mechanism to mark a property as not participating in derived
> conformances? One instance might be that I have a memoization/cache related
> property that is stored but should not be considered when equating two
> instances.
>
> TJ
> On Tue, May 16, 2017 at 3:51 AM, Xiaodi Wu via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>> On Mon, May 15, 2017 at 7:18 PM, Tony Allevato <tony.allevato at gmail.com>
>> wrote:
>>
>>>
>>>
>>> On Mon, May 15, 2017 at 4:38 PM Itai Ferber <iferber at apple.com> wrote:
>>>
>>>> On May 15, 2017, at 4:03 PM, Xiaodi Wu via swift-evolution <
>>>> swift-evolution at swift.org> wrote:
>>>>
>>>> This is nice. Thanks for taking the time to write it up. I do have some
>>>> concerns/questions:
>>>>
>>>> Do the rules you spell out align with those for Codable? I think it is
>>>> very important that these are paralleled as closely as possible, and that
>>>> any deviations are explicitly called out in the text with reasoning as to
>>>> why it must deviate. Knowing when something is synthesized is difficult
>>>> enough with one set of rules--two is certainly one too many.
>>>>
>>>> To spell out the rules of Codable conformance clearly, for reference:
>>>>
>>>> For example, is it permitted to extend a type in the same module in
>>>> order to obtain synthesized Codable conformance? How about for a type in a
>>>> different module? The same rules should then apply for Equatable and
>>>> Hashable synthesis.
>>>>
>>>> Yes, Codable conformance can be added in an extension both
>>>> intra-module, and inter-module (i.e. you can add Codable conformance via
>>>> extensions in your own module, or to types in other modules). If there is a
>>>> situation where this is not possible, that’s likely a bug.
>>>> [For reference, it is actually easier to allow this than to prevent it.
>>>> I had to do very little extra work to support this because of how this is
>>>> organized in the compiler.]
>>>>
>>>
>>> To the best of my knowledge, the Equatable/Hashable synthesis I added
>>> uses the same rules as Codable, since I based my implementation on it.
>>>
>>> This is slightly different than what we initially discussed in this
>>> thread, which was that we should not support synthesized conformance in
>>> extensions in other modules. But after implementing it, my feeling is that
>>> if it falls out naturally and prohibiting it would be more work, then we
>>> shouldn't do that unless we have good reason to, and we should do it
>>> consistently with other derivations. So I'm using the same model.
>>>
>>>
>>>
>>>> Furthermore, does Codable ignore computed properties? If not, then
>>>> neither should Equatable and Hashable.
>>>>
>>>> Yes. Derived conformance for Codable ignores all computed properties
>>>> (including lazy properties and their associated storage). This is also some
>>>> relatively easy default behavior; you can iterate all properties matching
>>>> this requirement via `NominalTypeDecl.getStoredProperties`
>>>> (getStoredProperties(/*skipInaccessible=*/true) will skip the storage
>>>> associated with lazy vars).
>>>> [The thought process here is that accessing computed vars (and more so
>>>> lazy vars) will generally have side effects. We don’t want to trigger side
>>>> effects on encoding/checking for equality/hashing, and in general, those
>>>> types of properties will not affect equality/hash value/encoded
>>>> representation.]
>>>>
>>>
>>> Yes, I'm using the same getStoredProperties call to find the struct
>>> members to apply it to (thanks Itai for the early pointers!), so Eq/Hash
>>> should be synthesized for structs under the same conditions as Codable.
>>>
>>>
>>>>
>>>> There are also some complicated rules with generics, if I recall, that
>>>> may force something to be a computed property. It would be worth exploring
>>>> if such rules make ignoring computed properties counterintuitive. For
>>>> instance, if a user has to redesign the type, changing a stored property to
>>>> a computed property just to satisfy certain rules of the language, and all
>>>> of a sudden the definition of equality has silently changed as a
>>>> consequence, then that could end up being very hard to debug. If we find
>>>> that this is a plausible issue, then it might be worth considering refusing
>>>> to synthesize Equatable conformance for a type with any computed
>>>> properties--obviously limiting, but better limiting than surprising. To be
>>>> clear, I'm not suggesting that we do make this limitation, just that I
>>>> don't know that the consequences have been adequately explored for not
>>>> including computed properties.
>>>>
>>>> I’m not sure about this — someone else will have to weigh in. I don’t
>>>> think I’ve ever encountered a situation like this while working on Codable.
>>>> That being said, if there’s a limiting factor here that we encounter, we
>>>> should absolutely be consistent between all implementations of derived
>>>> conformance.
>>>>
>>>
>>> The concern that changing a stored property to a computed property would
>>> silently change the behavior of Eq/Hash is definitely something we should
>>> be aware of and we should see if it's something that people run into
>>> frequently once they start using the synthesis. Nothing obvious comes to
>>> mind as a way of preventing or warning about it, though—I'd have to think
>>> more on it.
>>>
>>>
>>>> It would be helpful to document these rules somewhere, so noted.
>>>>
>>>
>>> +1.
>>>
>>
>> Highly agree with all your responses; also, delighted to hear that the
>> implementation work has fallen into place so naturally.
>>
>>
>>
>> _______________________________________________
>> 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/20170516/5563df5a/attachment.html>


More information about the swift-evolution mailing list