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

2017-05-16 Thread Jordan Rose via swift-evolution
One additional point that could justify leaving out classes: because classes 
have reference semantics, it's not always clear that "all members are equal" 
implies "these instances are equal". Class instances have identity, which may 
be significant when deciding whether two objects are "the same".

(Thanks for writing this up, Tony!)

Jordan


> On May 5, 2017, at 12:18, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> Hmm, with these complications, I regret suggesting that this could be 
> extended to classes so easily. Definitely some interesting solutions, but my 
> inclination as well would be to leave classes out entirely for the moment and 
> let it percolate for Swift 4.1+. After all, it's an additive convenience.

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-16 Thread Tony Allevato via swift-evolution
Correct, that's not supported yet (it's in the limitations section of the
proposal). The first version is very limited in scope to support the common
cases, and additional features can be added later if needed.

Anything we would add to support omitting properties would likely also
apply to Codable, so it's better to do that in that context as well and not
just limit it to Eq/Hash.
On Tue, May 16, 2017 at 5:24 AM Xiaodi Wu  wrote:

> 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  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@swift.org> wrote:
>>
>>> On Mon, May 15, 2017 at 7:18 PM, Tony Allevato 
>>> wrote:
>>>


 On Mon, May 15, 2017 at 4:38 PM Itai Ferber  wrote:

> On May 15, 2017, at 4:03 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@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, 

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

2017-05-16 Thread Xiaodi Wu via swift-evolution
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  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@swift.org> wrote:
>
>> On Mon, May 15, 2017 at 7:18 PM, Tony Allevato 
>> wrote:
>>
>>>
>>>
>>> On Mon, May 15, 2017 at 4:38 PM Itai Ferber  wrote:
>>>
 On May 15, 2017, at 4:03 PM, Xiaodi Wu via swift-evolution <
 swift-evolution@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 

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

2017-05-16 Thread T.J. Usiyan via swift-evolution
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@swift.org> wrote:

> On Mon, May 15, 2017 at 7:18 PM, Tony Allevato 
> wrote:
>
>>
>>
>> On Mon, May 15, 2017 at 4:38 PM Itai Ferber  wrote:
>>
>>> On May 15, 2017, at 4:03 PM, Xiaodi Wu via swift-evolution <
>>> swift-evolution@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 

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

2017-05-15 Thread Xiaodi Wu via swift-evolution
On Mon, May 15, 2017 at 7:18 PM, Tony Allevato 
wrote:

>
>
> On Mon, May 15, 2017 at 4:38 PM Itai Ferber  wrote:
>
>> On May 15, 2017, at 4:03 PM, Xiaodi Wu via swift-evolution <
>> swift-evolution@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 

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

2017-05-15 Thread Tony Allevato via swift-evolution
On Mon, May 15, 2017 at 4:38 PM Itai Ferber  wrote:

> On May 15, 2017, at 4:03 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@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.


>
> On Mon, May 15, 2017 at 17:21 Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> Yes—the PR of the proposal is here:
>> https://github.com/apple/swift-evolution/pull/706
>>
>> It needs to be updated slightly—I'll remove the references to the
>> "multiplicative hash 

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

2017-05-15 Thread Tony Allevato via swift-evolution
Just to update everyone on the thread—it took a little longer than I'd
hoped to get the kinks out, but I finally have the implementation up as a
PR: https://github.com/apple/swift/pull/9619

Hopefully there's still enough time to get the proposal reviewed, make any
changes needed, and get this into Swift 4!


On Tue, May 9, 2017 at 10:27 PM Brent Royal-Gordon 
wrote:

> On May 9, 2017, at 3:53 PM, Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Likewise, proposing a new public addition to the standard library would
> inspire far more design discussion than I believe we have time for if we
> want this to make Swift 4. :)
>
>
> Agreed. What I would do here is add an `_combineHashes` function (or
> `Hashable` extension method, or whatever is most convenient) to the
> standard library in Swift 4, have your compiler magic feature use it, and
> defer the name-and-interface discussion until Swift 5.
>
> --
> Brent Royal-Gordon
> Architechies
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-15 Thread Itai Ferber via swift-evolution

> On May 15, 2017, at 4:03 PM, Xiaodi Wu via swift-evolution 
>  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.]

> 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.]

> 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. 

It would be helpful to document these rules somewhere, so noted.

> On Mon, May 15, 2017 at 17:21 Tony Allevato via swift-evolution 
> > wrote:
> Yes—the PR of the proposal is here: 
> https://github.com/apple/swift-evolution/pull/706 
> 
> 
> It needs to be updated slightly—I'll remove the references to the 
> "multiplicative hash function" recommendation because I ended up using the 
> existing _mixInt and xor, which is how the standard library implements its 
> Collection hashValues. (The proposal probably really doesn't need to state 
> anything about the hash function used, and its entirely an implementation 
> detail.)
> 
> 
> On Mon, May 15, 2017 at 3:18 PM Andrew Bennett  > wrote:
> Nice work Tony! Is this proposal up for PR on swift-evolution as well?
> 
> On Tue, 16 May 2017 at 7:30 am, Tony Allevato  > wrote:
> Just to update everyone on the thread—it took a little longer than I'd hoped 
> to get the kinks out, but I finally have the implementation up as a PR: 
> https://github.com/apple/swift/pull/9619 
> 
> 
> Hopefully there's still enough time to get the proposal reviewed, make any 
> changes needed, and get this into Swift 4!
> 
> 
> On Tue, May 9, 2017 at 10:27 PM Brent Royal-Gordon  > wrote:
>> On May 9, 2017, at 3:53 PM, Tony Allevato via swift-evolution 
>> 

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

2017-05-15 Thread Xiaodi Wu via swift-evolution
Oh, and to add, the details of hashing may not need to be fully written
out, but it would be nice to mention that it will follow existing standard
library practice--or, if not, then why, and also any implications related
to hash collision security issues. Moreover, it may be worth mentioning
that the synthesized method involves mixing the _hashes_ of members and not
their memory representation--though it may seem obvious.


On Mon, May 15, 2017 at 17:21 Tony Allevato via swift-evolution <
swift-evolution@swift.org> wrote:

> Yes—the PR of the proposal is here:
> https://github.com/apple/swift-evolution/pull/706
>
> It needs to be updated slightly—I'll remove the references to the
> "multiplicative hash function" recommendation because I ended up using the
> existing _mixInt and xor, which is how the standard library implements its
> Collection hashValues. (The proposal probably really doesn't need to state
> anything about the hash function used, and its entirely an implementation
> detail.)
>
>
> On Mon, May 15, 2017 at 3:18 PM Andrew Bennett  wrote:
>
>> Nice work Tony! Is this proposal up for PR on swift-evolution as well?
>>
>> On Tue, 16 May 2017 at 7:30 am, Tony Allevato 
>> wrote:
>>
>>> Just to update everyone on the thread—it took a little longer than I'd
>>> hoped to get the kinks out, but I finally have the implementation up as a
>>> PR: https://github.com/apple/swift/pull/9619
>>>
>>> Hopefully there's still enough time to get the proposal reviewed, make
>>> any changes needed, and get this into Swift 4!
>>>
>>>
>>> On Tue, May 9, 2017 at 10:27 PM Brent Royal-Gordon <
>>> br...@architechies.com> wrote:
>>>
 On May 9, 2017, at 3:53 PM, Tony Allevato via swift-evolution <
 swift-evolution@swift.org> wrote:

 Likewise, proposing a new public addition to the standard library would
 inspire far more design discussion than I believe we have time for if we
 want this to make Swift 4. :)


 Agreed. What I would do here is add an `_combineHashes` function (or
 `Hashable` extension method, or whatever is most convenient) to the
 standard library in Swift 4, have your compiler magic feature use it, and
 defer the name-and-interface discussion until Swift 5.

 --
 Brent Royal-Gordon
 Architechies

 ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-15 Thread Xiaodi Wu via swift-evolution
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.

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.

Furthermore, does Codable ignore computed properties? If not, then neither
should Equatable and Hashable. 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.


On Mon, May 15, 2017 at 17:21 Tony Allevato via swift-evolution <
swift-evolution@swift.org> wrote:

> Yes—the PR of the proposal is here:
> https://github.com/apple/swift-evolution/pull/706
>
> It needs to be updated slightly—I'll remove the references to the
> "multiplicative hash function" recommendation because I ended up using the
> existing _mixInt and xor, which is how the standard library implements its
> Collection hashValues. (The proposal probably really doesn't need to state
> anything about the hash function used, and its entirely an implementation
> detail.)
>
>
> On Mon, May 15, 2017 at 3:18 PM Andrew Bennett  wrote:
>
>> Nice work Tony! Is this proposal up for PR on swift-evolution as well?
>>
>> On Tue, 16 May 2017 at 7:30 am, Tony Allevato 
>> wrote:
>>
>>> Just to update everyone on the thread—it took a little longer than I'd
>>> hoped to get the kinks out, but I finally have the implementation up as a
>>> PR: https://github.com/apple/swift/pull/9619
>>>
>>> Hopefully there's still enough time to get the proposal reviewed, make
>>> any changes needed, and get this into Swift 4!
>>>
>>>
>>> On Tue, May 9, 2017 at 10:27 PM Brent Royal-Gordon <
>>> br...@architechies.com> wrote:
>>>
 On May 9, 2017, at 3:53 PM, Tony Allevato via swift-evolution <
 swift-evolution@swift.org> wrote:

 Likewise, proposing a new public addition to the standard library would
 inspire far more design discussion than I believe we have time for if we
 want this to make Swift 4. :)


 Agreed. What I would do here is add an `_combineHashes` function (or
 `Hashable` extension method, or whatever is most convenient) to the
 standard library in Swift 4, have your compiler magic feature use it, and
 defer the name-and-interface discussion until Swift 5.

 --
 Brent Royal-Gordon
 Architechies

 ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-15 Thread Tony Allevato via swift-evolution
Yes—the PR of the proposal is here:
https://github.com/apple/swift-evolution/pull/706

It needs to be updated slightly—I'll remove the references to the
"multiplicative hash function" recommendation because I ended up using the
existing _mixInt and xor, which is how the standard library implements its
Collection hashValues. (The proposal probably really doesn't need to state
anything about the hash function used, and its entirely an implementation
detail.)


On Mon, May 15, 2017 at 3:18 PM Andrew Bennett  wrote:

> Nice work Tony! Is this proposal up for PR on swift-evolution as well?
>
> On Tue, 16 May 2017 at 7:30 am, Tony Allevato 
> wrote:
>
>> Just to update everyone on the thread—it took a little longer than I'd
>> hoped to get the kinks out, but I finally have the implementation up as a
>> PR: https://github.com/apple/swift/pull/9619
>>
>> Hopefully there's still enough time to get the proposal reviewed, make
>> any changes needed, and get this into Swift 4!
>>
>>
>> On Tue, May 9, 2017 at 10:27 PM Brent Royal-Gordon <
>> br...@architechies.com> wrote:
>>
>>> On May 9, 2017, at 3:53 PM, Tony Allevato via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
>>> Likewise, proposing a new public addition to the standard library would
>>> inspire far more design discussion than I believe we have time for if we
>>> want this to make Swift 4. :)
>>>
>>>
>>> Agreed. What I would do here is add an `_combineHashes` function (or
>>> `Hashable` extension method, or whatever is most convenient) to the
>>> standard library in Swift 4, have your compiler magic feature use it, and
>>> defer the name-and-interface discussion until Swift 5.
>>>
>>> --
>>> Brent Royal-Gordon
>>> Architechies
>>>
>>>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-15 Thread Andrew Bennett via swift-evolution
Nice work Tony! Is this proposal up for PR on swift-evolution as well?

On Tue, 16 May 2017 at 7:30 am, Tony Allevato 
wrote:

> Just to update everyone on the thread—it took a little longer than I'd
> hoped to get the kinks out, but I finally have the implementation up as a
> PR: https://github.com/apple/swift/pull/9619
>
> Hopefully there's still enough time to get the proposal reviewed, make any
> changes needed, and get this into Swift 4!
>
>
> On Tue, May 9, 2017 at 10:27 PM Brent Royal-Gordon 
> wrote:
>
>> On May 9, 2017, at 3:53 PM, Tony Allevato via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> Likewise, proposing a new public addition to the standard library would
>> inspire far more design discussion than I believe we have time for if we
>> want this to make Swift 4. :)
>>
>>
>> Agreed. What I would do here is add an `_combineHashes` function (or
>> `Hashable` extension method, or whatever is most convenient) to the
>> standard library in Swift 4, have your compiler magic feature use it, and
>> defer the name-and-interface discussion until Swift 5.
>>
>> --
>> Brent Royal-Gordon
>> Architechies
>>
>>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-09 Thread Brent Royal-Gordon via swift-evolution
> On May 9, 2017, at 3:53 PM, Tony Allevato via swift-evolution 
>  wrote:
> 
> Likewise, proposing a new public addition to the standard library would 
> inspire far more design discussion than I believe we have time for if we want 
> this to make Swift 4. :)


Agreed. What I would do here is add an `_combineHashes` function (or `Hashable` 
extension method, or whatever is most convenient) to the standard library in 
Swift 4, have your compiler magic feature use it, and defer the 
name-and-interface discussion until Swift 5.

-- 
Brent Royal-Gordon
Architechies

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-09 Thread Andrew Bennett via swift-evolution
I suspected that would be the case with the function, thanks for confirming
Tony.

I agree with Tony that it's not worth slowing down this proposal to get
tuples in, although it would be nice if this proposal applied to all value
types. Thanks for pursuing this proposal, I have no intention of preventing
it from making Swift 4 :)

I'm happy to help with the implementation if that helps get it in, I'd
already started one before I realised you had a branch (I was the one who
message you on twitter).

To clarify though, tuples are a structural type (not nominal), I don't
think that iterating the structure is a hack. I doubt that tuples will get
protocol conformance for a long time.


On Wed, May 10, 2017 at 9:52 AM, Xiaodi Wu  wrote:

> On Tue, May 9, 2017 at 5:53 PM, Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> While I agree that it would be nice to handle tuples in those contexts,
>> it also adds a fair amount of complexity to the implementation of the
>> synthesis. I imagine that time would be better spent just making tuples
>> conform to Equatable/Hashable properly instead of hacking it, because then
>> the support falls out naturally; I'd strongly prefer not to squeeze in more
>> special cases to the proposal that could be done additively later.
>>
>> Likewise, proposing a new public addition to the standard library would
>> inspire far more design discussion than I believe we have time for if we
>> want this to make Swift 4. :)
>>
>
> Agree. Instead of adding more hacks to tuples, their being synthesized to
> conform to Equatable (and Hashable) is long overdue and all of this will
> fall out naturally. As it's additive, it'll happen when it happens. There
> will need to be a way to combine hashes together, of course, but a public
> API is certainly its own proposal.
>
>
> On Tue, May 9, 2017 at 3:48 PM Andrew Bennett  wrote:
>>
>>> Also, when implementing this proposal it's going to be necessary to
>>> combine multiple hashes together. It would be awesome if this was done in a
>>> reusable way. If it doesn't slow the proposal down it would be awesome if
>>> it also introduced a stdlib function:
>>>
>>> public func combine_hashes(_ elements: [Int]) -> Int {
>>>
>>> ...
>>>
>>> }
>>>
>>> Thanks!
>>> Andrew
>>>
>>> On Wed, May 10, 2017 at 8:45 AM, Andrew Bennett 
>>> wrote:
>>>
 You state that you will not synthesise conformance for tuples, I agree
 with this, but if a struct or enum holds a tuple it would be nice if it
 could be hashed if its members are all hashable.

 struct A {

   var a: Int, b: Int, c: Int

 }


 struct B {

   var tuple: (a: Int, b: Int, c: Int)

 }

 I'd consider these two to be equivalent as far as this proposal is
 concerned, it would be nice if the proposal made that explicit.


 On Tue, May 9, 2017 at 7:17 AM, Tony Allevato via swift-evolution <
 swift-evolution@swift.org> wrote:

>
>
> On Mon, May 8, 2017 at 2:11 PM Matthew Johnson 
> wrote:
>
>> On May 8, 2017, at 4:02 PM, Tony Allevato 
>> wrote:
>>
>> On Sat, May 6, 2017 at 4:17 PM Chris Lattner 
>> wrote:
>>
>>> On May 5, 2017, at 11:33 AM, Tony Allevato via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
>>>
>>>

 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;
>>>
>>>
>>> Please follow the precedent of the Codable proposal as closely as
>>> possible.  If you’d like this to be successful for Swift 4, you should 
>>> look
>>> to scope it as narrowly as possible.  Because it is additive (with 
>>> opt-in),
>>> it can always be extended in the future.
>>>
>>> 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.
>>>
>>>
>>> This proposal doesn’t need to cover all cases, since it is just
>>> sugaring a (very common) situation.  Conditional conformances to 
>>> Hashable
>>> could be written manually.
>>>
>>> I'm less sure about conformances being added in other modules,
>>>
>>>
>>> It is a bad idea, it would break 

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

2017-05-09 Thread Xiaodi Wu via swift-evolution
On Tue, May 9, 2017 at 5:53 PM, Tony Allevato via swift-evolution <
swift-evolution@swift.org> wrote:

> While I agree that it would be nice to handle tuples in those contexts, it
> also adds a fair amount of complexity to the implementation of the
> synthesis. I imagine that time would be better spent just making tuples
> conform to Equatable/Hashable properly instead of hacking it, because then
> the support falls out naturally; I'd strongly prefer not to squeeze in more
> special cases to the proposal that could be done additively later.
>
> Likewise, proposing a new public addition to the standard library would
> inspire far more design discussion than I believe we have time for if we
> want this to make Swift 4. :)
>

Agree. Instead of adding more hacks to tuples, their being synthesized to
conform to Equatable (and Hashable) is long overdue and all of this will
fall out naturally. As it's additive, it'll happen when it happens. There
will need to be a way to combine hashes together, of course, but a public
API is certainly its own proposal.


On Tue, May 9, 2017 at 3:48 PM Andrew Bennett  wrote:
>
>> Also, when implementing this proposal it's going to be necessary to
>> combine multiple hashes together. It would be awesome if this was done in a
>> reusable way. If it doesn't slow the proposal down it would be awesome if
>> it also introduced a stdlib function:
>>
>> public func combine_hashes(_ elements: [Int]) -> Int {
>>
>> ...
>>
>> }
>>
>> Thanks!
>> Andrew
>>
>> On Wed, May 10, 2017 at 8:45 AM, Andrew Bennett  wrote:
>>
>>> You state that you will not synthesise conformance for tuples, I agree
>>> with this, but if a struct or enum holds a tuple it would be nice if it
>>> could be hashed if its members are all hashable.
>>>
>>> struct A {
>>>
>>>   var a: Int, b: Int, c: Int
>>>
>>> }
>>>
>>>
>>> struct B {
>>>
>>>   var tuple: (a: Int, b: Int, c: Int)
>>>
>>> }
>>>
>>> I'd consider these two to be equivalent as far as this proposal is
>>> concerned, it would be nice if the proposal made that explicit.
>>>
>>>
>>> On Tue, May 9, 2017 at 7:17 AM, Tony Allevato via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>


 On Mon, May 8, 2017 at 2:11 PM Matthew Johnson 
 wrote:

> On May 8, 2017, at 4:02 PM, Tony Allevato 
> wrote:
>
> On Sat, May 6, 2017 at 4:17 PM Chris Lattner 
> wrote:
>
>> On May 5, 2017, at 11:33 AM, Tony Allevato via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>
>>
>>>
>>> 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;
>>
>>
>> Please follow the precedent of the Codable proposal as closely as
>> possible.  If you’d like this to be successful for Swift 4, you should 
>> look
>> to scope it as narrowly as possible.  Because it is additive (with 
>> opt-in),
>> it can always be extended in the future.
>>
>> 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.
>>
>>
>> This proposal doesn’t need to cover all cases, since it is just
>> sugaring a (very common) situation.  Conditional conformances to Hashable
>> could be written manually.
>>
>> I'm less sure about conformances being added in other modules,
>>
>>
>> It is a bad idea, it would break resilience of the extended type.
>>
>> 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.
>>
>>
>> Agreed, keep it narrow to start with.
>>
>> Also, I don’t know how the rest of the core team feels about this,
>> but I suspect that they will be reticent to take an additive proposal at
>> this late point in the schedule, unless someone is willing to step up to
>> provide an implementation.
>>
>
> That someone is me :)  I have a branch where it's working for enums
> (modulo some weirdness I need to fix after rebasing a two-month-old 
> state),
> and adapting that logic to structs should hopefully be straightforward
> after that. Going with the more narrowly-scoped proposal and making
> conformances explicit simplifies the 

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

2017-05-09 Thread Jose Cheyo Jimenez via swift-evolution
Hi Andrew, 

Implicitly making Tuples Hashable should be its own proposal. Take a look at 
the Equable Tuple proposal as a template. 
https://github.com/apple/swift-evolution/blob/master/proposals/0015-tuple-comparison-operators.md
 


Thanks


> On May 9, 2017, at 3:45 PM, Andrew Bennett via swift-evolution 
>  wrote:
> 
> You state that you will not synthesise conformance for tuples, I agree with 
> this, but if a struct or enum holds a tuple it would be nice if it could be 
> hashed if its members are all hashable.
> 
> struct A {
>   var a: Int, b: Int, c: Int
> }
> 
> struct B {
>   var tuple: (a: Int, b: Int, c: Int)
> }
> 
> I'd consider these two to be equivalent as far as this proposal is concerned, 
> it would be nice if the proposal made that explicit.
> 
> 
> On Tue, May 9, 2017 at 7:17 AM, Tony Allevato via swift-evolution 
> > wrote:
> 
> 
> On Mon, May 8, 2017 at 2:11 PM Matthew Johnson  > wrote:
>> On May 8, 2017, at 4:02 PM, Tony Allevato > > wrote:
>> 
>> On Sat, May 6, 2017 at 4:17 PM Chris Lattner > > wrote:
>> On May 5, 2017, at 11:33 AM, Tony Allevato via swift-evolution 
>> > wrote:
>>> 
>>> 
>>> 
>>> 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;
>> 
>> Please follow the precedent of the Codable proposal as closely as possible.  
>> If you’d like this to be successful for Swift 4, you should look to scope it 
>> as narrowly as possible.  Because it is additive (with opt-in), it can 
>> always be extended in the future.
>> 
>>> 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.
>> 
>> This proposal doesn’t need to cover all cases, since it is just sugaring a 
>> (very common) situation.  Conditional conformances to Hashable could be 
>> written manually.
>> 
>>> I'm less sure about conformances being added in other modules,
>> 
>> It is a bad idea, it would break resilience of the extended type.
>> 
>>> 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.
>> 
>> Agreed, keep it narrow to start with.
>> 
>> Also, I don’t know how the rest of the core team feels about this, but I 
>> suspect that they will be reticent to take an additive proposal at this late 
>> point in the schedule, unless someone is willing to step up to provide an 
>> implementation.
>> 
>> That someone is me :)  I have a branch where it's working for enums (modulo 
>> some weirdness I need to fix after rebasing a two-month-old state), and 
>> adapting that logic to structs should hopefully be straightforward after 
>> that. Going with the more narrowly-scoped proposal and making conformances 
>> explicit simplifies the implementation a great deal as well (I was 
>> previously blocked with recursive types when it was implicit).
>> 
>> Thanks for the feedback—after consideration, I've pulled classes out of the 
>> proposal completely (even non-final) and mentioned the other limitations so 
>> we'd have a record of what was discussed in this thread.
>> 
>> I've created a PR for the proposal text, in the event that the core team is 
>> interested in moving this forward: 
>> https://github.com/apple/swift-evolution/pull/706 
>> 
> Thanks for continuing to push this forward Tony!  The current proposal looks 
> like the right approach for getting this into Swift 4.  
> 
> I only have one question which I will present with an example:
> 
> protocol Foo: Equatable {}
> protocol Bar: Hashable {}
> 
> struct FooType: Foo {}
> struct BarType: Bar {}
> 
> Do FooType and BarType receive synthesis?
> 
> Great question! Yes they should. It's "explicit" transitively since the 
> answer to "does FooType/BarType conform to Equatable/Hashable?" is still 
> "yes". (And I've confirmed that my prototype handles this case.)
> 
> This is especially helpful since Hashable extends Equatable, so a user only 
> needs to list conformance to the former to get correctly synthesized 

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

2017-05-09 Thread Tony Allevato via swift-evolution
While I agree that it would be nice to handle tuples in those contexts, it
also adds a fair amount of complexity to the implementation of the
synthesis. I imagine that time would be better spent just making tuples
conform to Equatable/Hashable properly instead of hacking it, because then
the support falls out naturally; I'd strongly prefer not to squeeze in more
special cases to the proposal that could be done additively later.

Likewise, proposing a new public addition to the standard library would
inspire far more design discussion than I believe we have time for if we
want this to make Swift 4. :)


On Tue, May 9, 2017 at 3:48 PM Andrew Bennett  wrote:

> Also, when implementing this proposal it's going to be necessary to
> combine multiple hashes together. It would be awesome if this was done in a
> reusable way. If it doesn't slow the proposal down it would be awesome if
> it also introduced a stdlib function:
>
> public func combine_hashes(_ elements: [Int]) -> Int {
>
> ...
>
> }
>
> Thanks!
> Andrew
>
> On Wed, May 10, 2017 at 8:45 AM, Andrew Bennett  wrote:
>
>> You state that you will not synthesise conformance for tuples, I agree
>> with this, but if a struct or enum holds a tuple it would be nice if it
>> could be hashed if its members are all hashable.
>>
>> struct A {
>>
>>   var a: Int, b: Int, c: Int
>>
>> }
>>
>>
>> struct B {
>>
>>   var tuple: (a: Int, b: Int, c: Int)
>>
>> }
>>
>> I'd consider these two to be equivalent as far as this proposal is
>> concerned, it would be nice if the proposal made that explicit.
>>
>>
>> On Tue, May 9, 2017 at 7:17 AM, Tony Allevato via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>>
>>>
>>> On Mon, May 8, 2017 at 2:11 PM Matthew Johnson 
>>> wrote:
>>>
 On May 8, 2017, at 4:02 PM, Tony Allevato 
 wrote:

 On Sat, May 6, 2017 at 4:17 PM Chris Lattner 
 wrote:

> On May 5, 2017, at 11:33 AM, Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
>
>>
>> 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;
>
>
> Please follow the precedent of the Codable proposal as closely as
> possible.  If you’d like this to be successful for Swift 4, you should 
> look
> to scope it as narrowly as possible.  Because it is additive (with 
> opt-in),
> it can always be extended in the future.
>
> 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.
>
>
> This proposal doesn’t need to cover all cases, since it is just
> sugaring a (very common) situation.  Conditional conformances to Hashable
> could be written manually.
>
> I'm less sure about conformances being added in other modules,
>
>
> It is a bad idea, it would break resilience of the extended type.
>
> 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.
>
>
> Agreed, keep it narrow to start with.
>
> Also, I don’t know how the rest of the core team feels about this, but
> I suspect that they will be reticent to take an additive proposal at this
> late point in the schedule, unless someone is willing to step up to 
> provide
> an implementation.
>

 That someone is me :)  I have a branch where it's working for enums
 (modulo some weirdness I need to fix after rebasing a two-month-old state),
 and adapting that logic to structs should hopefully be straightforward
 after that. Going with the more narrowly-scoped proposal and making
 conformances explicit simplifies the implementation a great deal as well (I
 was previously blocked with recursive types when it was implicit).

 Thanks for the feedback—after consideration, I've pulled classes out of
 the proposal completely (even non-final) and mentioned the other
 limitations so we'd have a record of what was discussed in this thread.

 I've created a PR for the proposal text, in the event that the core
 team is interested in moving this forward:
 https://github.com/apple/swift-evolution/pull/706


 Thanks for continuing to push this forward Tony!  The 

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

2017-05-09 Thread Andrew Bennett via swift-evolution
Also, when implementing this proposal it's going to be necessary to combine
multiple hashes together. It would be awesome if this was done in a
reusable way. If it doesn't slow the proposal down it would be awesome if
it also introduced a stdlib function:

public func combine_hashes(_ elements: [Int]) -> Int {

...

}

Thanks!
Andrew

On Wed, May 10, 2017 at 8:45 AM, Andrew Bennett  wrote:

> You state that you will not synthesise conformance for tuples, I agree
> with this, but if a struct or enum holds a tuple it would be nice if it
> could be hashed if its members are all hashable.
>
> struct A {
>
>   var a: Int, b: Int, c: Int
>
> }
>
>
> struct B {
>
>   var tuple: (a: Int, b: Int, c: Int)
>
> }
>
> I'd consider these two to be equivalent as far as this proposal is
> concerned, it would be nice if the proposal made that explicit.
>
>
> On Tue, May 9, 2017 at 7:17 AM, Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>>
>>
>> On Mon, May 8, 2017 at 2:11 PM Matthew Johnson 
>> wrote:
>>
>>> On May 8, 2017, at 4:02 PM, Tony Allevato 
>>> wrote:
>>>
>>> On Sat, May 6, 2017 at 4:17 PM Chris Lattner 
>>> wrote:
>>>
 On May 5, 2017, at 11:33 AM, Tony Allevato via swift-evolution <
 swift-evolution@swift.org> wrote:



>
> 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;


 Please follow the precedent of the Codable proposal as closely as
 possible.  If you’d like this to be successful for Swift 4, you should look
 to scope it as narrowly as possible.  Because it is additive (with opt-in),
 it can always be extended in the future.

 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.


 This proposal doesn’t need to cover all cases, since it is just
 sugaring a (very common) situation.  Conditional conformances to Hashable
 could be written manually.

 I'm less sure about conformances being added in other modules,


 It is a bad idea, it would break resilience of the extended type.

 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.


 Agreed, keep it narrow to start with.

 Also, I don’t know how the rest of the core team feels about this, but
 I suspect that they will be reticent to take an additive proposal at this
 late point in the schedule, unless someone is willing to step up to provide
 an implementation.

>>>
>>> That someone is me :)  I have a branch where it's working for enums
>>> (modulo some weirdness I need to fix after rebasing a two-month-old state),
>>> and adapting that logic to structs should hopefully be straightforward
>>> after that. Going with the more narrowly-scoped proposal and making
>>> conformances explicit simplifies the implementation a great deal as well (I
>>> was previously blocked with recursive types when it was implicit).
>>>
>>> Thanks for the feedback—after consideration, I've pulled classes out of
>>> the proposal completely (even non-final) and mentioned the other
>>> limitations so we'd have a record of what was discussed in this thread.
>>>
>>> I've created a PR for the proposal text, in the event that the core team
>>> is interested in moving this forward: https://github.com/ap
>>> ple/swift-evolution/pull/706
>>>
>>>
>>> Thanks for continuing to push this forward Tony!  The current proposal
>>> looks like the right approach for getting this into Swift 4.
>>>
>>> I only have one question which I will present with an example:
>>>
>>> protocol Foo: Equatable {}
>>> protocol Bar: Hashable {}
>>>
>>> struct FooType: Foo {}
>>> struct BarType: Bar {}
>>>
>>> Do FooType and BarType receive synthesis?
>>>
>>
>> Great question! Yes they should. It's "explicit" transitively since the
>> answer to "does FooType/BarType conform to Equatable/Hashable?" is still
>> "yes". (And I've confirmed that my prototype handles this case.)
>>
>> This is especially helpful since Hashable extends Equatable, so a user
>> only needs to list conformance to the former to get correctly synthesized
>> implementations of both, which helps to guarantee that they're implemented
>> consistently with respect to each other.
>>
>>

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

2017-05-09 Thread Andrew Bennett via swift-evolution
You state that you will not synthesise conformance for tuples, I agree with
this, but if a struct or enum holds a tuple it would be nice if it could be
hashed if its members are all hashable.

struct A {

  var a: Int, b: Int, c: Int

}


struct B {

  var tuple: (a: Int, b: Int, c: Int)

}

I'd consider these two to be equivalent as far as this proposal is
concerned, it would be nice if the proposal made that explicit.


On Tue, May 9, 2017 at 7:17 AM, Tony Allevato via swift-evolution <
swift-evolution@swift.org> wrote:

>
>
> On Mon, May 8, 2017 at 2:11 PM Matthew Johnson 
> wrote:
>
>> On May 8, 2017, at 4:02 PM, Tony Allevato 
>> wrote:
>>
>> On Sat, May 6, 2017 at 4:17 PM Chris Lattner  wrote:
>>
>>> On May 5, 2017, at 11:33 AM, Tony Allevato via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
>>>
>>>

 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;
>>>
>>>
>>> Please follow the precedent of the Codable proposal as closely as
>>> possible.  If you’d like this to be successful for Swift 4, you should look
>>> to scope it as narrowly as possible.  Because it is additive (with opt-in),
>>> it can always be extended in the future.
>>>
>>> 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.
>>>
>>>
>>> This proposal doesn’t need to cover all cases, since it is just sugaring
>>> a (very common) situation.  Conditional conformances to Hashable could be
>>> written manually.
>>>
>>> I'm less sure about conformances being added in other modules,
>>>
>>>
>>> It is a bad idea, it would break resilience of the extended type.
>>>
>>> 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.
>>>
>>>
>>> Agreed, keep it narrow to start with.
>>>
>>> Also, I don’t know how the rest of the core team feels about this, but I
>>> suspect that they will be reticent to take an additive proposal at this
>>> late point in the schedule, unless someone is willing to step up to provide
>>> an implementation.
>>>
>>
>> That someone is me :)  I have a branch where it's working for enums
>> (modulo some weirdness I need to fix after rebasing a two-month-old state),
>> and adapting that logic to structs should hopefully be straightforward
>> after that. Going with the more narrowly-scoped proposal and making
>> conformances explicit simplifies the implementation a great deal as well (I
>> was previously blocked with recursive types when it was implicit).
>>
>> Thanks for the feedback—after consideration, I've pulled classes out of
>> the proposal completely (even non-final) and mentioned the other
>> limitations so we'd have a record of what was discussed in this thread.
>>
>> I've created a PR for the proposal text, in the event that the core team
>> is interested in moving this forward: https://github.com/
>> apple/swift-evolution/pull/706
>>
>>
>> Thanks for continuing to push this forward Tony!  The current proposal
>> looks like the right approach for getting this into Swift 4.
>>
>> I only have one question which I will present with an example:
>>
>> protocol Foo: Equatable {}
>> protocol Bar: Hashable {}
>>
>> struct FooType: Foo {}
>> struct BarType: Bar {}
>>
>> Do FooType and BarType receive synthesis?
>>
>
> Great question! Yes they should. It's "explicit" transitively since the
> answer to "does FooType/BarType conform to Equatable/Hashable?" is still
> "yes". (And I've confirmed that my prototype handles this case.)
>
> This is especially helpful since Hashable extends Equatable, so a user
> only needs to list conformance to the former to get correctly synthesized
> implementations of both, which helps to guarantee that they're implemented
> consistently with respect to each other.
>
>
>
>>
>>
>>
>>
>>>
>>> -Chris
>>>
>>>
>>>
>>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-08 Thread Matthew Johnson via swift-evolution

> On May 8, 2017, at 4:17 PM, Tony Allevato  wrote:
> 
> 
> 
> On Mon, May 8, 2017 at 2:11 PM Matthew Johnson  > wrote:
>> On May 8, 2017, at 4:02 PM, Tony Allevato > > wrote:
>> 
>> On Sat, May 6, 2017 at 4:17 PM Chris Lattner > > wrote:
>> On May 5, 2017, at 11:33 AM, Tony Allevato via swift-evolution 
>> > wrote:
>>> 
>>> 
>>> 
>>> 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;
>> 
>> Please follow the precedent of the Codable proposal as closely as possible.  
>> If you’d like this to be successful for Swift 4, you should look to scope it 
>> as narrowly as possible.  Because it is additive (with opt-in), it can 
>> always be extended in the future.
>> 
>>> 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.
>> 
>> This proposal doesn’t need to cover all cases, since it is just sugaring a 
>> (very common) situation.  Conditional conformances to Hashable could be 
>> written manually.
>> 
>>> I'm less sure about conformances being added in other modules,
>> 
>> It is a bad idea, it would break resilience of the extended type.
>> 
>>> 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.
>> 
>> Agreed, keep it narrow to start with.
>> 
>> Also, I don’t know how the rest of the core team feels about this, but I 
>> suspect that they will be reticent to take an additive proposal at this late 
>> point in the schedule, unless someone is willing to step up to provide an 
>> implementation.
>> 
>> That someone is me :)  I have a branch where it's working for enums (modulo 
>> some weirdness I need to fix after rebasing a two-month-old state), and 
>> adapting that logic to structs should hopefully be straightforward after 
>> that. Going with the more narrowly-scoped proposal and making conformances 
>> explicit simplifies the implementation a great deal as well (I was 
>> previously blocked with recursive types when it was implicit).
>> 
>> Thanks for the feedback—after consideration, I've pulled classes out of the 
>> proposal completely (even non-final) and mentioned the other limitations so 
>> we'd have a record of what was discussed in this thread.
>> 
>> I've created a PR for the proposal text, in the event that the core team is 
>> interested in moving this forward: 
>> https://github.com/apple/swift-evolution/pull/706 
>> 
> Thanks for continuing to push this forward Tony!  The current proposal looks 
> like the right approach for getting this into Swift 4.  
> 
> I only have one question which I will present with an example:
> 
> protocol Foo: Equatable {}
> protocol Bar: Hashable {}
> 
> struct FooType: Foo {}
> struct BarType: Bar {}
> 
> Do FooType and BarType receive synthesis?
> 
> Great question! Yes they should. It's "explicit" transitively since the 
> answer to "does FooType/BarType conform to Equatable/Hashable?" is still 
> "yes". (And I've confirmed that my prototype handles this case.)
> 
> This is especially helpful since Hashable extends Equatable, so a user only 
> needs to list conformance to the former to get correctly synthesized 
> implementations of both, which helps to guarantee that they're implemented 
> consistently with respect to each other.

Great.  This is what I was hoping to hear.  :)

> 
>  
> 
>> 
>>  
>> 
>> -Chris

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-08 Thread Tony Allevato via swift-evolution
On Mon, May 8, 2017 at 2:11 PM Matthew Johnson 
wrote:

> On May 8, 2017, at 4:02 PM, Tony Allevato  wrote:
>
> On Sat, May 6, 2017 at 4:17 PM Chris Lattner  wrote:
>
>> On May 5, 2017, at 11:33 AM, Tony Allevato via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>
>>
>>>
>>> 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;
>>
>>
>> Please follow the precedent of the Codable proposal as closely as
>> possible.  If you’d like this to be successful for Swift 4, you should look
>> to scope it as narrowly as possible.  Because it is additive (with opt-in),
>> it can always be extended in the future.
>>
>> 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.
>>
>>
>> This proposal doesn’t need to cover all cases, since it is just sugaring
>> a (very common) situation.  Conditional conformances to Hashable could be
>> written manually.
>>
>> I'm less sure about conformances being added in other modules,
>>
>>
>> It is a bad idea, it would break resilience of the extended type.
>>
>> 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.
>>
>>
>> Agreed, keep it narrow to start with.
>>
>> Also, I don’t know how the rest of the core team feels about this, but I
>> suspect that they will be reticent to take an additive proposal at this
>> late point in the schedule, unless someone is willing to step up to provide
>> an implementation.
>>
>
> That someone is me :)  I have a branch where it's working for enums
> (modulo some weirdness I need to fix after rebasing a two-month-old state),
> and adapting that logic to structs should hopefully be straightforward
> after that. Going with the more narrowly-scoped proposal and making
> conformances explicit simplifies the implementation a great deal as well (I
> was previously blocked with recursive types when it was implicit).
>
> Thanks for the feedback—after consideration, I've pulled classes out of
> the proposal completely (even non-final) and mentioned the other
> limitations so we'd have a record of what was discussed in this thread.
>
> I've created a PR for the proposal text, in the event that the core team
> is interested in moving this forward:
> https://github.com/apple/swift-evolution/pull/706
>
>
> Thanks for continuing to push this forward Tony!  The current proposal
> looks like the right approach for getting this into Swift 4.
>
> I only have one question which I will present with an example:
>
> protocol Foo: Equatable {}
> protocol Bar: Hashable {}
>
> struct FooType: Foo {}
> struct BarType: Bar {}
>
> Do FooType and BarType receive synthesis?
>

Great question! Yes they should. It's "explicit" transitively since the
answer to "does FooType/BarType conform to Equatable/Hashable?" is still
"yes". (And I've confirmed that my prototype handles this case.)

This is especially helpful since Hashable extends Equatable, so a user only
needs to list conformance to the former to get correctly synthesized
implementations of both, which helps to guarantee that they're implemented
consistently with respect to each other.



>
>
>
>
>>
>> -Chris
>>
>>
>>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-08 Thread Matthew Johnson via swift-evolution

> On May 8, 2017, at 4:02 PM, Tony Allevato  wrote:
> 
> On Sat, May 6, 2017 at 4:17 PM Chris Lattner  > wrote:
> On May 5, 2017, at 11:33 AM, Tony Allevato via swift-evolution 
> > wrote:
>> 
>> 
>> 
>> 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;
> 
> Please follow the precedent of the Codable proposal as closely as possible.  
> If you’d like this to be successful for Swift 4, you should look to scope it 
> as narrowly as possible.  Because it is additive (with opt-in), it can always 
> be extended in the future.
> 
>> 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.
> 
> This proposal doesn’t need to cover all cases, since it is just sugaring a 
> (very common) situation.  Conditional conformances to Hashable could be 
> written manually.
> 
>> I'm less sure about conformances being added in other modules,
> 
> It is a bad idea, it would break resilience of the extended type.
> 
>> 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.
> 
> Agreed, keep it narrow to start with.
> 
> Also, I don’t know how the rest of the core team feels about this, but I 
> suspect that they will be reticent to take an additive proposal at this late 
> point in the schedule, unless someone is willing to step up to provide an 
> implementation.
> 
> That someone is me :)  I have a branch where it's working for enums (modulo 
> some weirdness I need to fix after rebasing a two-month-old state), and 
> adapting that logic to structs should hopefully be straightforward after 
> that. Going with the more narrowly-scoped proposal and making conformances 
> explicit simplifies the implementation a great deal as well (I was previously 
> blocked with recursive types when it was implicit).
> 
> Thanks for the feedback—after consideration, I've pulled classes out of the 
> proposal completely (even non-final) and mentioned the other limitations so 
> we'd have a record of what was discussed in this thread.
> 
> I've created a PR for the proposal text, in the event that the core team is 
> interested in moving this forward: 
> https://github.com/apple/swift-evolution/pull/706 
> 
Thanks for continuing to push this forward Tony!  The current proposal looks 
like the right approach for getting this into Swift 4.  

I only have one question which I will present with an example:

protocol Foo: Equatable {}
protocol Bar: Hashable {}

struct FooType: Foo {}
struct BarType: Bar {}

Do FooType and BarType receive synthesis?

> 
>  
> 
> -Chris
> 
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-08 Thread Tony Allevato via swift-evolution
On Sat, May 6, 2017 at 4:17 PM Chris Lattner  wrote:

> On May 5, 2017, at 11:33 AM, Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
>
>>
>> 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;
>
>
> Please follow the precedent of the Codable proposal as closely as
> possible.  If you’d like this to be successful for Swift 4, you should look
> to scope it as narrowly as possible.  Because it is additive (with opt-in),
> it can always be extended in the future.
>
> 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.
>
>
> This proposal doesn’t need to cover all cases, since it is just sugaring a
> (very common) situation.  Conditional conformances to Hashable could be
> written manually.
>
> I'm less sure about conformances being added in other modules,
>
>
> It is a bad idea, it would break resilience of the extended type.
>
> 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.
>
>
> Agreed, keep it narrow to start with.
>
> Also, I don’t know how the rest of the core team feels about this, but I
> suspect that they will be reticent to take an additive proposal at this
> late point in the schedule, unless someone is willing to step up to provide
> an implementation.
>

That someone is me :)  I have a branch where it's working for enums (modulo
some weirdness I need to fix after rebasing a two-month-old state), and
adapting that logic to structs should hopefully be straightforward after
that. Going with the more narrowly-scoped proposal and making conformances
explicit simplifies the implementation a great deal as well (I was
previously blocked with recursive types when it was implicit).

Thanks for the feedback—after consideration, I've pulled classes out of the
proposal completely (even non-final) and mentioned the other limitations so
we'd have a record of what was discussed in this thread.

I've created a PR for the proposal text, in the event that the core team is
interested in moving this forward:
https://github.com/apple/swift-evolution/pull/706



>
> -Chris
>
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-08 Thread Matthew Johnson via swift-evolution

> On May 8, 2017, at 3:17 PM, Michael Ilseman via swift-evolution 
>  wrote:
> 
> If an extension on your type declares a hashValue property, what should be 
> the semantics? Is that an error (conflicts with default provided one), or is 
> that one used?

How does Codable handle the equivalent question?

> 
>> On May 4, 2017, at 3:20 PM, Andrew Bennett via swift-evolution 
>> > wrote:
>> 
>> That's correct, consistent with Encoding/Decoding (SE-0166 
>> )
>>  it is sufficient to just do this:
>> 
>> struct MyType: Hashable {
>>   var foo: Int
>>   var bar: Float
>> }
>> 
>> Now MyType should get a generated implementation because each member is also 
>> Hashable.
>> 
>> There's more details in the proposal near:
>> An enum T that derives Equatable will receive a compiler-generated 
>> implementation of
>> 
>> 
>> 
>> On Fri, May 5, 2017 at 8:15 AM, Xiaodi Wu > > wrote:
>> I'm imagining no syntax; effectively, as though there exists an "extension 
>> Equatable where [ all members : Equatable ]" with a default implementation.
>> 
>> 
>> On Thu, May 4, 2017 at 17:13 John McCall > > wrote:
>>> On May 4, 2017, at 6:10 PM, Andrew Bennett via swift-evolution 
>>> > wrote:
>>> I agree, let's make it opt-in.
>>> 
>>> This looks really great, I'm excited to get generated conformance for 
>>> Equatable/Hashable in time for Swift 4.
>>> 
>>> I think it's worth mentioning that Encoding/Decoding generated conformance 
>>> is already accepted and implemented in Swift 4. The implementation and 
>>> acceptance criterion for Equatable/Hashable is likely to be very similar.
>>> 
>>> For the open questions, I think for the sake of getting this into Swift 4 
>>> we should go for explicit derivation, and don't allow omission of fields 
>>> (yet).
>> 
>> Is there a syntax proposal for explicit derivation?  Or are you imagining 
>> that just declaring the conformance but failing to implement it should 
>> trigger derivation?
>> 
>> John.
>> 
>>> 
>>> Omission is nice-to-have, but likely to be a long-winded bike-shed.
>>> 
>>> Changing from explicit to implicit is a loss of information, and has a 
>>> large impact on the language, it can't easily be undone, so it requires a 
>>> large discussion when it's decided. It only adds a little additional 
>>> convenience to the user though.
>>> 
>>> I suggest we discuss implicit generation and allowing omission with 
>>> follow-up proposals, they will very likely be additive non-breaking 
>>> changes. For this proposal we play it safe and stick to explicit 
>>> conformance and no omission of fields.
>>> 
>>> 
>>> On Fri, May 5, 2017 at 8:01 AM, Xiaodi Wu via swift-evolution 
>>> > wrote:
>>> Hmm, I can see the appeal of automatically deriving Equatable and Hashable 
>>> conformance, but I'd like that to be opt-in. That is, types should declare 
>>> that they are Equatable or Hashable to begin with. It wouldn't have to take 
>>> extra syntax, as compiler magic could effectively synthesize default 
>>> implementations for == and/or hashValue when all members are themselves 
>>> Equatable or Hashable, respectively. With such a scheme, consideration can 
>>> be made to accommodating classes too.
>>> On Thu, May 4, 2017 at 15:37 Tony Allevato via swift-evolution 
>>> > wrote:
>>> Hi all,
>>> 
>>> A conversation on Twitter last night brought up some interest in this 
>>> feature and I was encouraged to revive this proposal.
>>> 
>>> Jordan Rose mentioned 
>>>  on Twitter that it 
>>> could possibly make it in by the Swift 4 deadline if others contributed—I 
>>> have a WIP branch (albeit not currently working because I rebased after a 
>>> couple months of it being idle) that does the work for enums but I got 
>>> stuck on the mutually recursive cases. If this got approved, I'd love to 
>>> collaborate with other interested folks to finish up the implementation.
>>> 
>>> Link: https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad 
>>> 
>>> 
>>> 
>>> Deriving Equatable and Hashable for value types
>>> 
>>> Proposal: SE- 
>>> 
>>> Author(s): Tony Allevato 
>>> Status: Awaiting review 
>>> 
>>> Review manager: TBD
>>>  
>>> Introduction

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

2017-05-08 Thread Michael Ilseman via swift-evolution
If an extension on your type declares a hashValue property, what should be the 
semantics? Is that an error (conflicts with default provided one), or is that 
one used?

> On May 4, 2017, at 3:20 PM, Andrew Bennett via swift-evolution 
>  wrote:
> 
> That's correct, consistent with Encoding/Decoding (SE-0166 
> )
>  it is sufficient to just do this:
> 
> struct MyType: Hashable {
>   var foo: Int
>   var bar: Float
> }
> 
> Now MyType should get a generated implementation because each member is also 
> Hashable.
> 
> There's more details in the proposal near:
> An enum T that derives Equatable will receive a compiler-generated 
> implementation of
> 
> 
> 
> On Fri, May 5, 2017 at 8:15 AM, Xiaodi Wu  > wrote:
> I'm imagining no syntax; effectively, as though there exists an "extension 
> Equatable where [ all members : Equatable ]" with a default implementation.
> 
> 
> On Thu, May 4, 2017 at 17:13 John McCall  > wrote:
>> On May 4, 2017, at 6:10 PM, Andrew Bennett via swift-evolution 
>> > wrote:
>> I agree, let's make it opt-in.
>> 
>> This looks really great, I'm excited to get generated conformance for 
>> Equatable/Hashable in time for Swift 4.
>> 
>> I think it's worth mentioning that Encoding/Decoding generated conformance 
>> is already accepted and implemented in Swift 4. The implementation and 
>> acceptance criterion for Equatable/Hashable is likely to be very similar.
>> 
>> For the open questions, I think for the sake of getting this into Swift 4 we 
>> should go for explicit derivation, and don't allow omission of fields (yet).
> 
> Is there a syntax proposal for explicit derivation?  Or are you imagining 
> that just declaring the conformance but failing to implement it should 
> trigger derivation?
> 
> John.
> 
>> 
>> Omission is nice-to-have, but likely to be a long-winded bike-shed.
>> 
>> Changing from explicit to implicit is a loss of information, and has a large 
>> impact on the language, it can't easily be undone, so it requires a large 
>> discussion when it's decided. It only adds a little additional convenience 
>> to the user though.
>> 
>> I suggest we discuss implicit generation and allowing omission with 
>> follow-up proposals, they will very likely be additive non-breaking changes. 
>> For this proposal we play it safe and stick to explicit conformance and no 
>> omission of fields.
>> 
>> 
>> On Fri, May 5, 2017 at 8:01 AM, Xiaodi Wu via swift-evolution 
>> > wrote:
>> Hmm, I can see the appeal of automatically deriving Equatable and Hashable 
>> conformance, but I'd like that to be opt-in. That is, types should declare 
>> that they are Equatable or Hashable to begin with. It wouldn't have to take 
>> extra syntax, as compiler magic could effectively synthesize default 
>> implementations for == and/or hashValue when all members are themselves 
>> Equatable or Hashable, respectively. With such a scheme, consideration can 
>> be made to accommodating classes too.
>> On Thu, May 4, 2017 at 15:37 Tony Allevato via swift-evolution 
>> > wrote:
>> Hi all,
>> 
>> A conversation on Twitter last night brought up some interest in this 
>> feature and I was encouraged to revive this proposal.
>> 
>> Jordan Rose mentioned 
>>  on Twitter that it 
>> could possibly make it in by the Swift 4 deadline if others contributed—I 
>> have a WIP branch (albeit not currently working because I rebased after a 
>> couple months of it being idle) that does the work for enums but I got stuck 
>> on the mutually recursive cases. If this got approved, I'd love to 
>> collaborate with other interested folks to finish up the implementation.
>> 
>> Link: https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad 
>> 
>> 
>> 
>> Deriving Equatable and Hashable for value types
>> 
>> Proposal: SE- 
>> 
>> Author(s): Tony Allevato 
>> Status: Awaiting review 
>> 
>> Review manager: TBD
>>  
>> Introduction
>> 
>> Value types are prevalent throughout the Swift language, and we encourage 
>> developers to think in those terms when writing their own types. Frequently, 
>> developers have to write large amounts of boilerplate code to support 
>> equatability and hashability of value types. This proposal offers a 

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

2017-05-06 Thread Chris Lattner via swift-evolution
On May 5, 2017, at 11:33 AM, Tony Allevato via swift-evolution 
 wrote:
> 
> 
> 
> 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;

Please follow the precedent of the Codable proposal as closely as possible.  If 
you’d like this to be successful for Swift 4, you should look to scope it as 
narrowly as possible.  Because it is additive (with opt-in), it can always be 
extended in the future.

> 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.

This proposal doesn’t need to cover all cases, since it is just sugaring a 
(very common) situation.  Conditional conformances to Hashable could be written 
manually.

> I'm less sure about conformances being added in other modules,

It is a bad idea, it would break resilience of the extended type.

> 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.

Agreed, keep it narrow to start with.

Also, I don’t know how the rest of the core team feels about this, but I 
suspect that they will be reticent to take an additive proposal at this late 
point in the schedule, unless someone is willing to step up to provide an 
implementation.

-Chris


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-06 Thread Chris Lattner via swift-evolution

> On May 4, 2017, at 3:01 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> Hmm, I can see the appeal of automatically deriving Equatable and Hashable 
> conformance, but I'd like that to be opt-in. That is, types should declare 
> that they are Equatable or Hashable to begin with. It wouldn't have to take 
> extra syntax, as compiler magic could effectively synthesize default 
> implementations for == and/or hashValue when all members are themselves 
> Equatable or Hashable, respectively. With such a scheme, consideration can be 
> made to accommodating classes too.

Completely agreed.

-Chris



> On Thu, May 4, 2017 at 15:37 Tony Allevato via swift-evolution 
> > wrote:
> Hi all,
> 
> A conversation on Twitter last night brought up some interest in this feature 
> and I was encouraged to revive this proposal.
> 
> Jordan Rose mentioned 
>  on Twitter that it 
> could possibly make it in by the Swift 4 deadline if others contributed—I 
> have a WIP branch (albeit not currently working because I rebased after a 
> couple months of it being idle) that does the work for enums but I got stuck 
> on the mutually recursive cases. If this got approved, I'd love to 
> collaborate with other interested folks to finish up the implementation.
> 
> Link: https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad 
> 
> 
> 
> Deriving Equatable and Hashable for value types
> 
> Proposal: SE- 
> 
> Author(s): Tony Allevato 
> Status: Awaiting review 
> 
> Review manager: TBD
>  
> Introduction
> 
> Value types are prevalent throughout the Swift language, and we encourage 
> developers to think in those terms when writing their own types. Frequently, 
> developers have to write large amounts of boilerplate code to support 
> equatability and hashability of value types. This proposal offers a way for 
> the compiler to automatically derive conformance to Equatable and Hashable to 
> reduce this boilerplate, in a subset of scenarios where generating the 
> correct implementation is known to be possible.
> 
> Swift-evolution thread: Universal Equatability, Hashability, and 
> Comparability 
>  
> Motivation
> 
> Building robust value types in Swift can involve writing significant 
> boilerplate code to support hashability and equatability. Equality is 
> pervasive across many value types, and for each one users must implement the 
> == operator such that it performs a fairly rote memberwise equality test. As 
> an example, an equality test for a struct looks fairly uninteresting:
> 
> struct Foo: Equatable {
>   static func == (lhs: Foo, rhs: Foo) -> Bool {
> return lhs.property1 == rhs.property1 &&
>lhs.property2 == rhs.property2 &&
>lhs.property3 == rhs.property3 &&
>...
>   }
> }
> What's worse is that this operator must be updated if any properties are 
> added, removed, or changed, and since it must be manually written, it's 
> possible to get it wrong, either by omission or typographical error.
> 
> Likewise, hashability is necessary when one wishes to store a value type in a 
> Set or use one as a multi-valued Dictionary key. Writing high-quality, 
> well-distributed hash functions is not trivial so developers may not put a 
> great deal of thought into them – especially as the number of properties 
> increases – not realizing that their performance could potentially suffer as 
> a result. And as with equality, writing it manually means there is the 
> potential to get it wrong.
> 
> In particular, the code that must be written to implement equality for enums 
> is quite verbose:
> 
> enum Token: Equatable {
>   case string(String)
>   case number(Int)
>   case lparen
>   case rparen
>   
>   static func == (lhs: Token, rhs: Token) -> Bool {
> switch (lhs, rhs) {
> case (.string(let lhsString), .string(let rhsString)):
>   return lhsString == rhsString
> case (.number(let lhsNumber), .number(let lhsNumber)):
>   return lhsNumber == rhsNumber
> case (.lparen, .lparen), (.rparen, .rparen):
>   return true
> default:
>   return false
> }
>   }
> }
> Crafting a high-quality hash function for this enum would be similarly 
> inconvenient to write.
> 
> Swift already derives Equatable and Hashable conformance for a small subset 
> of enums: those for which the cases have no associated values (including 
> enums with raw types). 

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

2017-05-05 Thread Xiaodi Wu via swift-evolution
It would have to be compiler magic. If I recall, the only factor preventing
it is that no one has implemented it, but one of the core team members has
noted that it should be fairly straightforward. I don't have the time right
now or I'd seriously take a stab at it.


On Fri, May 5, 2017 at 14:20 Tony Allevato  wrote:

> On Fri, May 5, 2017 at 12:18 PM Xiaodi Wu  wrote:
>
>> Hmm, with these complications, I regret suggesting that this could be
>> extended to classes so easily. Definitely some interesting solutions, but
>> my inclination as well would be to leave classes out entirely for the
>> moment and let it percolate for Swift 4.1+. After all, it's an additive
>> convenience.
>>
>> Any thought as to including tuples though?
>>
>
> Can non-nominal types conform to protocols? I thought that was the main
> limitation for supporting these conformances on tuples.
>
> I would love to support them if possible to get rid of the arbitrary ==
> implementations in the standard library and make multi-component dictionary
> keys easier to work with, but my understanding was that the above issue was
> the bigger factor preventing it.
>
>
>
>
>> On Fri, May 5, 2017 at 13:51 Matthew Johnson via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> On May 5, 2017, at 1:33 PM, Tony Allevato 
>>> wrote:
>>>
>>>
>>>
>>> On Fri, May 5, 2017 at 11:07 AM Matthew Johnson 
>>> wrote:
>>>
 On May 5, 2017, at 10:45 AM, Tony Allevato via swift-evolution <
 swift-evolution@swift.org> wrote:

 Thanks for your feedback, everybody!


 Thanks for continuing to drive this forward!


 I've updated the gist
  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 

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

2017-05-05 Thread Tony Allevato via swift-evolution
On Fri, May 5, 2017 at 12:18 PM Xiaodi Wu  wrote:

> Hmm, with these complications, I regret suggesting that this could be
> extended to classes so easily. Definitely some interesting solutions, but
> my inclination as well would be to leave classes out entirely for the
> moment and let it percolate for Swift 4.1+. After all, it's an additive
> convenience.
>
> Any thought as to including tuples though?
>

Can non-nominal types conform to protocols? I thought that was the main
limitation for supporting these conformances on tuples.

I would love to support them if possible to get rid of the arbitrary ==
implementations in the standard library and make multi-component dictionary
keys easier to work with, but my understanding was that the above issue was
the bigger factor preventing it.




> On Fri, May 5, 2017 at 13:51 Matthew Johnson via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> On May 5, 2017, at 1:33 PM, Tony Allevato 
>> wrote:
>>
>>
>>
>> On Fri, May 5, 2017 at 11:07 AM Matthew Johnson 
>> wrote:
>>
>>> On May 5, 2017, at 10:45 AM, Tony Allevato via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
>>> Thanks for your feedback, everybody!
>>>
>>>
>>> Thanks for continuing to drive this forward!
>>>
>>>
>>> I've updated the gist
>>>  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?
>>
>>
>> This won’t work because Equatable has a `Self` requirement so the `==`
>> defined by the initial conforming class would be called.  In order to
>> support non-final classes you would need to have that dispatch through
>> something like an `isEqual` method which *can* be 

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

2017-05-05 Thread Xiaodi Wu via swift-evolution
Hmm, with these complications, I regret suggesting that this could be
extended to classes so easily. Definitely some interesting solutions, but
my inclination as well would be to leave classes out entirely for the
moment and let it percolate for Swift 4.1+. After all, it's an additive
convenience.

Any thought as to including tuples though?
On Fri, May 5, 2017 at 13:51 Matthew Johnson via swift-evolution <
swift-evolution@swift.org> wrote:

> On May 5, 2017, at 1:33 PM, Tony Allevato  wrote:
>
>
>
> On Fri, May 5, 2017 at 11:07 AM Matthew Johnson 
> wrote:
>
>> On May 5, 2017, at 10:45 AM, Tony Allevato via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> Thanks for your feedback, everybody!
>>
>>
>> Thanks for continuing to drive this forward!
>>
>>
>> I've updated the gist
>>  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?
>
>
> This won’t work because Equatable has a `Self` requirement so the `==`
> defined by the initial conforming class would be called.  In order to
> support non-final classes you would need to have that dispatch through
> something like an `isEqual` method which *can* be overridden.
>
>
> 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.
>
>
> Yes, this makes sense.  The primary difficulty with Hashable is that it
> refines Equatable.  Refining a non-final implementation of `hashValue` is
> relatively straightforward.
>
> * Sub is a subclass of Super. Super conforms to Hashable and implements a
> final hashValue. The compiler cannot derive one for Super and 

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

2017-05-05 Thread Matthew Johnson via swift-evolution

> On May 5, 2017, at 2:16 PM, Tony Allevato  wrote:
> 
> On Fri, May 5, 2017 at 11:51 AM Matthew Johnson  > wrote:
>> On May 5, 2017, at 1:33 PM, Tony Allevato > > wrote:
>> 
>> 
>> 
>> On Fri, May 5, 2017 at 11:07 AM Matthew Johnson > > wrote:
>>> On May 5, 2017, at 10:45 AM, Tony Allevato via swift-evolution 
>>> > wrote:
>>> 
>>> Thanks for your feedback, everybody!
>> 
>> Thanks for continuing to drive this forward!
>> 
>>> 
>>> I've updated the gist 
>>>  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?
> 
> This won’t work because Equatable has a `Self` requirement so the `==` 
> defined by the initial conforming class would be called.  In order to support 
> non-final classes you would need to have that dispatch through something like 
> an `isEqual` method which *can* be overridden.
> 
> Ah crap, you're right. I was basing my experimentation on this example:
> 
> class Base: Equatable {
>   let x: Int
>   init(x: Int) { self.x = x }
>   static func == (lhs: Base, rhs: Base) -> Bool { return lhs.x == rhs.x }
> }
> 
> class Sub: Base {
>   let y: Int
>   init(x: Int, y: Int) { self.y = y; super.init(x: x) }
> 
>   static func == (lhs: Sub, rhs: Sub) -> Bool {
> guard lhs as Base == rhs as Base else {
>   return false
> }
> return lhs.y == rhs.y
>   }
> }
> 
> let s1 = Sub(x: 1, y: 2)
> let s2 = Sub(x: 1, y: 3)
> let s3 = Sub(x: 1, y: 2)
> 
> func usesBase(_ lhs: Base, _ 

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

2017-05-05 Thread Tony Allevato via swift-evolution
On Fri, May 5, 2017 at 11:51 AM Matthew Johnson 
wrote:

> On May 5, 2017, at 1:33 PM, Tony Allevato  wrote:
>
>
>
> On Fri, May 5, 2017 at 11:07 AM Matthew Johnson 
> wrote:
>
>> On May 5, 2017, at 10:45 AM, Tony Allevato via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> Thanks for your feedback, everybody!
>>
>>
>> Thanks for continuing to drive this forward!
>>
>>
>> I've updated the gist
>>  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?
>
>
> This won’t work because Equatable has a `Self` requirement so the `==`
> defined by the initial conforming class would be called.  In order to
> support non-final classes you would need to have that dispatch through
> something like an `isEqual` method which *can* be overridden.
>

Ah crap, you're right. I was basing my experimentation on this example:

class Base: Equatable {
  let x: Int
  init(x: Int) { self.x = x }
  static func == (lhs: Base, rhs: Base) -> Bool { return lhs.x == rhs.x }
}

class Sub: Base {
  let y: Int
  init(x: Int, y: Int) { self.y = y; super.init(x: x) }

  static func == (lhs: Sub, rhs: Sub) -> Bool {
guard lhs as Base == rhs as Base else {
  return false
}
return lhs.y == rhs.y
  }
}

let s1 = Sub(x: 1, y: 2)
let s2 = Sub(x: 1, y: 3)
let s3 = Sub(x: 1, y: 2)

func usesBase(_ lhs: Base, _ rhs: Base) -> Bool { return lhs == rhs }
func usesSub(_ lhs: Sub, _ rhs: Sub) -> Bool { return lhs == rhs }

print(usesSub(s1, s2)) // false (expected)
print(usesSub(s1, s3)) // true

print(usesBase(s1, s2)) // true (problematic)
print(usesBase(s1, s3)) // true


In that case the problematic behavior is "expected", but when you make it
generic, you're right that 

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

2017-05-05 Thread Matthew Johnson via swift-evolution

> On May 5, 2017, at 1:33 PM, Tony Allevato  wrote:
> 
> 
> 
> On Fri, May 5, 2017 at 11:07 AM Matthew Johnson  > wrote:
>> On May 5, 2017, at 10:45 AM, Tony Allevato via swift-evolution 
>> > wrote:
>> 
>> Thanks for your feedback, everybody!
> 
> Thanks for continuing to drive this forward!
> 
>> 
>> I've updated the gist 
>>  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?

This won’t work because Equatable has a `Self` requirement so the `==` defined 
by the initial conforming class would be called.  In order to support non-final 
classes you would need to have that dispatch through something like an 
`isEqual` method which *can* be overridden.

> 
> 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.

Yes, this makes sense.  The primary difficulty with Hashable is that it refines 
Equatable.  Refining a non-final implementation of `hashValue` is relatively 
straightforward.

> * 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.

Do you mean “the compiler cannot derive one for Sub”?

> * 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 

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

2017-05-05 Thread Tony Allevato via swift-evolution
On Fri, May 5, 2017 at 11:07 AM Matthew Johnson 
wrote:

> On May 5, 2017, at 10:45 AM, Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Thanks for your feedback, everybody!
>
>
> Thanks for continuing to drive this forward!
>
>
> I've updated the gist
>  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
>  wrote:
>
>> On Fri, May 5, 2017 at 1:47 AM, Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> On Fri, May 5, 2017 at 12:41 AM, Brent Royal-Gordon <
>>> br...@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 

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

2017-05-05 Thread Matthew Johnson via swift-evolution

> On May 5, 2017, at 10:45 AM, Tony Allevato via swift-evolution 
>  wrote:
> 
> Thanks for your feedback, everybody!

Thanks for continuing to drive this forward!

> 
> I've updated the gist 
>  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.

> * 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.

> 
> 
> On Fri, May 5, 2017 at 8:16 AM Nevin Brackett-Rozinsky via swift-evolution 
> > wrote:
> On Fri, May 5, 2017 at 1:47 AM, Xiaodi Wu via swift-evolution 
> > wrote:
> On Fri, May 5, 2017 at 12:41 AM, Brent Royal-Gordon  > 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@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-05 Thread Tony Allevato via swift-evolution
Thanks for your feedback, everybody!

I've updated the gist
 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)
* 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.


On Fri, May 5, 2017 at 8:16 AM Nevin Brackett-Rozinsky via swift-evolution <
swift-evolution@swift.org> wrote:

> On Fri, May 5, 2017 at 1:47 AM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> On Fri, May 5, 2017 at 12:41 AM, Brent Royal-Gordon <
>> br...@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@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-05 Thread Nevin Brackett-Rozinsky via swift-evolution
On Fri, May 5, 2017 at 1:47 AM, Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:

> On Fri, May 5, 2017 at 12:41 AM, Brent Royal-Gordon <
> br...@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-04 Thread Brent Royal-Gordon via swift-evolution
> On May 4, 2017, at 3:01 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> Hmm, I can see the appeal of automatically deriving Equatable and Hashable 
> conformance, but I'd like that to be opt-in. That is, types should declare 
> that they are Equatable or Hashable to begin with. It wouldn't have to take 
> extra syntax, as compiler magic could effectively synthesize default 
> implementations for == and/or hashValue when all members are themselves 
> Equatable or Hashable, respectively.

Another benefit is that the problem you're currently having with recursion goes 
away: from outside the type, you merely need to check if conformance is 
declared.

Explicit with no special syntactic marker is definitely the way to go. It would 
work just like Codable is slated to.

> With such a scheme, consideration can be made to accommodating classes too.


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.

(My time is not unlimited right now, but I'd be willing to help with either the 
proposal or its implementation. This would be a great thing to get into Swift 
4.)

-- 
Brent Royal-Gordon
Architechies

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-05-04 Thread Xiaodi Wu via swift-evolution
I see. You're not suggesting magic.

The problem stands that the design of Equatable explicitly encourages the
distinction between identity and equality (it even says: "equality is
separate from identity"). It follows that we should *not* provide a default
implementation that forwards one to the other; if someone determines that
this is right for their particular class, then they can trivially write it
themselves.

This goes back to the very high bar for inclusion of something in the
standard library. An additional protocol like this needs to hold its own
weight, encourage rather than discourage patterns that we aim to promote,
help avoid rather than promote misuse, be commonly useful, and be difficult
to write on one's own--among other criteria outlined by Ben Cohen. For many
of these criteria, I think your proposed protocol does not pass the bar.

On Fri, May 5, 2017 at 00:06 Charlie Monroe 
wrote:

> On May 5, 2017, at 6:58 AM, Xiaodi Wu  wrote:
>
> As the documentation for Equatable discusses, the goal is to distinguish
> "equality" (==) from "identity" (===). If I understand it correctly, the
> goal is to *discourage* mixing the two concepts.
>
> Moreover, while writing a memberwise comparison is tedious and writing a
> memberwise hash is even error-prone, writing "return lhs === rhs" is both
> straightforward and impossible to mess up, so having special magic for that
> use case is much harder to justify.
>
>
> There doesn't need to be any magic - why would there need to be?
>
> public protocol PointerEquatable: AnyObject, Equatable, Hashable {
>
> public static func ==(lhs: Self, rhs: Self) -> Bool {
> return lhs === rhs
> }
>
> public var hashValue: Int {
> return ObjectIdentifier(self).hashValue
> }
>
> }
>
> I'm not saying it's super hard but while we're at it, we might as well
> include something like this in case identity is enough for equality, in
> such case
>
> class Foo: PointerEquatable { }
>
> is enough for the class to be hashable and equatable. It's all opt-in,
> there's no magic - I don't quite see the downside to it.
>
>
> On Thu, May 4, 2017 at 23:45 Charlie Monroe via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> I'm also leaning towards this being opt-in and the generation could be
>> triggered by having AutoEquatable and AutoHashable protocols.
>>
>> Any chance for this proposal to be extended by adding "PointerEquatable"
>> for classes? In many cases, pointer equality is just enough and having the
>> class equatable by pointer allows e.g. better array inter-op (e.g. removing
>> an object doesn't require getting an index first)...
>>
>>
>>
>> On May 4, 2017, at 10:37 PM, Tony Allevato via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> Hi all,
>>
>> A conversation on Twitter last night brought up some interest in this
>> feature and I was encouraged to revive this proposal.
>>
>> Jordan Rose mentioned
>>  on Twitter that
>> it could possibly make it in by the Swift 4 deadline if others
>> contributed—I have a WIP branch (albeit not currently working because I
>> rebased after a couple months of it being idle) that does the work for
>> enums but I got stuck on the mutually recursive cases. If this got
>> approved, I'd love to collaborate with other interested folks to finish up
>> the implementation.
>>
>> Link: https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad
>>
>>
>> Deriving Equatable and Hashable for value types
>>
>>- Proposal: SE-
>>
>> 
>>- Author(s): Tony Allevato 
>>- Status: Awaiting review
>>
>> 
>>- Review manager: TBD
>>
>>
>> 
>> Introduction
>>
>> Value types are prevalent throughout the Swift language, and we encourage
>> developers to think in those terms when writing their own types.
>> Frequently, developers have to write large amounts of boilerplate code to
>> support equatability and hashability of value types. This proposal offers a
>> way for the compiler to automatically derive conformance to Equatable and
>>  Hashable to reduce this boilerplate, in a subset of scenarios where
>> generating the correct implementation is known to be possible.
>>
>> Swift-evolution thread: Universal Equatability, Hashability, and
>> Comparability
>> 
>>
>> 
>> Motivation
>>
>> Building robust value types in Swift can involve writing significant
>> boilerplate code to support hashability and equatability. Equality is
>> pervasive across many value types, and for each one users must implement the
>>  == 

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

2017-05-04 Thread Charlie Monroe via swift-evolution

> On May 5, 2017, at 6:58 AM, Xiaodi Wu  wrote:
> 
> As the documentation for Equatable discusses, the goal is to distinguish 
> "equality" (==) from "identity" (===). If I understand it correctly, the goal 
> is to *discourage* mixing the two concepts.
> 
> Moreover, while writing a memberwise comparison is tedious and writing a 
> memberwise hash is even error-prone, writing "return lhs === rhs" is both 
> straightforward and impossible to mess up, so having special magic for that 
> use case is much harder to justify.

There doesn't need to be any magic - why would there need to be?

public protocol PointerEquatable: AnyObject, Equatable, Hashable {

public static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs === rhs
}

public var hashValue: Int {
return ObjectIdentifier(self).hashValue
}

}

I'm not saying it's super hard but while we're at it, we might as well include 
something like this in case identity is enough for equality, in such case

class Foo: PointerEquatable { }

is enough for the class to be hashable and equatable. It's all opt-in, there's 
no magic - I don't quite see the downside to it.


> On Thu, May 4, 2017 at 23:45 Charlie Monroe via swift-evolution 
> > wrote:
> I'm also leaning towards this being opt-in and the generation could be 
> triggered by having AutoEquatable and AutoHashable protocols.
> 
> Any chance for this proposal to be extended by adding "PointerEquatable" for 
> classes? In many cases, pointer equality is just enough and having the class 
> equatable by pointer allows e.g. better array inter-op (e.g. removing an 
> object doesn't require getting an index first)...
> 
> 
> 
>> On May 4, 2017, at 10:37 PM, Tony Allevato via swift-evolution 
>> > wrote:
>> 
>> Hi all,
>> 
>> A conversation on Twitter last night brought up some interest in this 
>> feature and I was encouraged to revive this proposal.
>> 
>> Jordan Rose mentioned 
>>  on Twitter that it 
>> could possibly make it in by the Swift 4 deadline if others contributed—I 
>> have a WIP branch (albeit not currently working because I rebased after a 
>> couple months of it being idle) that does the work for enums but I got stuck 
>> on the mutually recursive cases. If this got approved, I'd love to 
>> collaborate with other interested folks to finish up the implementation.
>> 
>> Link: https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad 
>> 
>> 
>> 
>> Deriving Equatable and Hashable for value types
>> 
>> Proposal: SE- 
>> 
>> Author(s): Tony Allevato 
>> Status: Awaiting review 
>> 
>> Review manager: TBD
>>  
>> Introduction
>> 
>> Value types are prevalent throughout the Swift language, and we encourage 
>> developers to think in those terms when writing their own types. Frequently, 
>> developers have to write large amounts of boilerplate code to support 
>> equatability and hashability of value types. This proposal offers a way for 
>> the compiler to automatically derive conformance to Equatable and Hashable 
>> to reduce this boilerplate, in a subset of scenarios where generating the 
>> correct implementation is known to be possible.
>> 
>> Swift-evolution thread: Universal Equatability, Hashability, and 
>> Comparability 
>>  
>> Motivation
>> 
>> Building robust value types in Swift can involve writing significant 
>> boilerplate code to support hashability and equatability. Equality is 
>> pervasive across many value types, and for each one users must implement the 
>> == operator such that it performs a fairly rote memberwise equality test. As 
>> an example, an equality test for a struct looks fairly uninteresting:
>> 
>> struct Foo: Equatable {
>>   static func == (lhs: Foo, rhs: Foo) -> Bool {
>> return lhs.property1 == rhs.property1 &&
>>lhs.property2 == rhs.property2 &&
>>lhs.property3 == rhs.property3 &&
>>...
>>   }
>> }
>> What's worse is that this operator must be updated if any properties are 
>> added, removed, or changed, and since it must be manually written, it's 
>> possible to get it wrong, either by omission or typographical error.
>> 
>> Likewise, hashability is necessary when one wishes to store a value type in 
>> a Set or use one as a multi-valued Dictionary key. Writing 

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

2017-05-04 Thread Xiaodi Wu via swift-evolution
As the documentation for Equatable discusses, the goal is to distinguish
"equality" (==) from "identity" (===). If I understand it correctly, the
goal is to *discourage* mixing the two concepts.

Moreover, while writing a memberwise comparison is tedious and writing a
memberwise hash is even error-prone, writing "return lhs === rhs" is both
straightforward and impossible to mess up, so having special magic for that
use case is much harder to justify.
On Thu, May 4, 2017 at 23:45 Charlie Monroe via swift-evolution <
swift-evolution@swift.org> wrote:

> I'm also leaning towards this being opt-in and the generation could be
> triggered by having AutoEquatable and AutoHashable protocols.
>
> Any chance for this proposal to be extended by adding "PointerEquatable"
> for classes? In many cases, pointer equality is just enough and having the
> class equatable by pointer allows e.g. better array inter-op (e.g. removing
> an object doesn't require getting an index first)...
>
>
>
> On May 4, 2017, at 10:37 PM, Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Hi all,
>
> A conversation on Twitter last night brought up some interest in this
> feature and I was encouraged to revive this proposal.
>
> Jordan Rose mentioned
>  on Twitter that
> it could possibly make it in by the Swift 4 deadline if others
> contributed—I have a WIP branch (albeit not currently working because I
> rebased after a couple months of it being idle) that does the work for
> enums but I got stuck on the mutually recursive cases. If this got
> approved, I'd love to collaborate with other interested folks to finish up
> the implementation.
>
> Link: https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad
>
>
> Deriving Equatable and Hashable for value types
>
>- Proposal: SE-
>
> 
>- Author(s): Tony Allevato 
>- Status: Awaiting review
>
> 
>- Review manager: TBD
>
>
> 
> Introduction
>
> Value types are prevalent throughout the Swift language, and we encourage
> developers to think in those terms when writing their own types.
> Frequently, developers have to write large amounts of boilerplate code to
> support equatability and hashability of value types. This proposal offers a
> way for the compiler to automatically derive conformance to Equatable and
> Hashable to reduce this boilerplate, in a subset of scenarios where
> generating the correct implementation is known to be possible.
>
> Swift-evolution thread: Universal Equatability, Hashability, and
> Comparability
> 
>
> 
> Motivation
>
> Building robust value types in Swift can involve writing significant
> boilerplate code to support hashability and equatability. Equality is
> pervasive across many value types, and for each one users must implement the
>  == operator such that it performs a fairly rote memberwise equality
> test. As an example, an equality test for a struct looks fairly
> uninteresting:
>
> struct Foo: Equatable {
>   static func == (lhs: Foo, rhs: Foo) -> Bool {
> return lhs.property1 == rhs.property1 &&
>lhs.property2 == rhs.property2 &&
>lhs.property3 == rhs.property3 &&
>...
>   }
> }
>
> What's worse is that this operator must be updated if any properties are
> added, removed, or changed, and since it must be manually written, it's
> possible to get it wrong, either by omission or typographical error.
>
> Likewise, hashability is necessary when one wishes to store a value type
> in a Set or use one as a multi-valued Dictionary key. Writing
> high-quality, well-distributed hash functions is not trivial so developers
> may not put a great deal of thought into them – especially as the number of
> properties increases – not realizing that their performance could
> potentially suffer as a result. And as with equality, writing it manually
> means there is the potential to get it wrong.
>
> In particular, the code that must be written to implement equality for
> enums is quite verbose:
>
> enum Token: Equatable {
>   case string(String)
>   case number(Int)
>   case lparen
>   case rparen
>
>   static func == (lhs: Token, rhs: Token) -> Bool {
> switch (lhs, rhs) {
> case (.string(let lhsString), .string(let rhsString)):
>   return lhsString == rhsString
> case (.number(let lhsNumber), .number(let lhsNumber)):
>   return lhsNumber == rhsNumber
> case (.lparen, .lparen), (.rparen, .rparen):
>   return true
> default:
>   return false
> }
>   }
> }
>
> Crafting a high-quality hash 

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

2017-05-04 Thread Matthew Johnson via swift-evolution

> On May 4, 2017, at 5:23 PM, Tony Allevato via swift-evolution 
>  wrote:
> 
> When I initially wrote an earlier version of this proposal last year, I was 
> imagining implicit derivation (as it is today for no-associated-value enums). 
> However, now that I'm deeper into it (and have tried implementing some of 
> it), I think explicit is the way to go.
> 
> My main reason for changing my mind is that I think it will make the mutually 
> recursive cases much easier. Today, with implicit derivation, I have to 
> traverse the full cycles to figure out if equatability/hashability permeates 
> through the full type graph starting from a particular type. With explicit 
> derivation, I should just be able to look at the immediate member types to 
> see if they *declare* the conformance, and if it can't be derived (because a 
> stored property/associated value is not E/H), then it's an error on *that* 
> type.
> 
> My only reservations have been the inconsistency with no-associated-value 
> enums and raw value enums, where the derivation is currently implicit. But I 
> think the benefits of making it explicit outweigh the disadvantages.
> 
> Regarding syntax, some folks in the last discussion on this topic preferred a 
> "derived" keyword, but I feel that's unnecessary, and if Codable provides 
> precedent for not having such a keyword, we should stick with that.

Huge +1 to this proposal and +1 to making it explicit following the precedent 
set by Codable.  Thank you for driving this forward Tony!

In addition to the specific examples in the proposal I think it’s important to 
point out that this proposal will make it more feasible in general for 
libraries require Equatable or Hashable conformances of user-supplied types - 
doing so will no longer place the burden of manual conformance on all of these 
types.

It would be nice to see enums without associated values require explicit 
conformance as well in the future but that should be a separate proposal.

> 
> On Thu, May 4, 2017 at 3:16 PM Xiaodi Wu via swift-evolution 
> > wrote:
> I'm imagining no syntax; effectively, as though there exists an "extension 
> Equatable where [ all members : Equatable ]" with a default implementation.
> 
> 
> On Thu, May 4, 2017 at 17:13 John McCall  > wrote:
>> On May 4, 2017, at 6:10 PM, Andrew Bennett via swift-evolution 
>> > wrote:
>> I agree, let's make it opt-in.
>> 
>> This looks really great, I'm excited to get generated conformance for 
>> Equatable/Hashable in time for Swift 4.
>> 
>> I think it's worth mentioning that Encoding/Decoding generated conformance 
>> is already accepted and implemented in Swift 4. The implementation and 
>> acceptance criterion for Equatable/Hashable is likely to be very similar.
>> 
>> For the open questions, I think for the sake of getting this into Swift 4 we 
>> should go for explicit derivation, and don't allow omission of fields (yet).
> 
> Is there a syntax proposal for explicit derivation?  Or are you imagining 
> that just declaring the conformance but failing to implement it should 
> trigger derivation?
> 
> John.
> 
>> 
>> Omission is nice-to-have, but likely to be a long-winded bike-shed.
>> 
>> Changing from explicit to implicit is a loss of information, and has a large 
>> impact on the language, it can't easily be undone, so it requires a large 
>> discussion when it's decided. It only adds a little additional convenience 
>> to the user though.
>> 
>> I suggest we discuss implicit generation and allowing omission with 
>> follow-up proposals, they will very likely be additive non-breaking changes. 
>> For this proposal we play it safe and stick to explicit conformance and no 
>> omission of fields.
>> 
>> 
>> On Fri, May 5, 2017 at 8:01 AM, Xiaodi Wu via swift-evolution 
>> > wrote:
>> Hmm, I can see the appeal of automatically deriving Equatable and Hashable 
>> conformance, but I'd like that to be opt-in. That is, types should declare 
>> that they are Equatable or Hashable to begin with. It wouldn't have to take 
>> extra syntax, as compiler magic could effectively synthesize default 
>> implementations for == and/or hashValue when all members are themselves 
>> Equatable or Hashable, respectively. With such a scheme, consideration can 
>> be made to accommodating classes too.
>> On Thu, May 4, 2017 at 15:37 Tony Allevato via swift-evolution 
>> > wrote:
>> Hi all,
>> 
>> A conversation on Twitter last night brought up some interest in this 
>> feature and I was encouraged to revive this proposal.
>> 
>> Jordan Rose mentioned 
>>  on Twitter that it 
>> could possibly make it in by the Swift 4 

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

2017-05-04 Thread Tony Allevato via swift-evolution
When I initially wrote an earlier version of this proposal last year, I was
imagining implicit derivation (as it is today for no-associated-value
enums). However, now that I'm deeper into it (and have tried implementing
some of it), I think explicit is the way to go.

My main reason for changing my mind is that I think it will make the
mutually recursive cases much easier. Today, with implicit derivation, I
have to traverse the full cycles to figure out if equatability/hashability
permeates through the full type graph starting from a particular type. With
explicit derivation, I should just be able to look at the immediate member
types to see if they *declare* the conformance, and if it can't be derived
(because a stored property/associated value is not E/H), then it's an error
on *that* type.

My only reservations have been the inconsistency with no-associated-value
enums and raw value enums, where the derivation is currently implicit. But
I think the benefits of making it explicit outweigh the disadvantages.

Regarding syntax, some folks in the last discussion on this topic preferred
a "derived" keyword, but I feel that's unnecessary, and if Codable provides
precedent for not having such a keyword, we should stick with that.

On Thu, May 4, 2017 at 3:16 PM Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:

> I'm imagining no syntax; effectively, as though there exists an "extension
> Equatable where [ all members : Equatable ]" with a default implementation.
>
>
> On Thu, May 4, 2017 at 17:13 John McCall  wrote:
>
>> On May 4, 2017, at 6:10 PM, Andrew Bennett via swift-evolution <
>> swift-evolution@swift.org> wrote:
>> I agree, let's make it opt-in.
>>
>> This looks really great, I'm excited to get generated conformance for
>> Equatable/Hashable in time for Swift 4.
>>
>> I think it's worth mentioning that Encoding/Decoding generated
>> conformance is already accepted and implemented in Swift 4. The
>> implementation and acceptance criterion for Equatable/Hashable is likely to
>> be very similar.
>>
>> *For the open questions*, I think for the sake of getting this into
>> Swift 4 we should go for explicit derivation, and don't allow omission of
>> fields (yet).
>>
>>
>> Is there a syntax proposal for explicit derivation?  Or are you imagining
>> that just declaring the conformance but failing to implement it should
>> trigger derivation?
>>
>> John.
>>
>>
>> Omission is nice-to-have, but likely to be a long-winded bike-shed.
>>
>> Changing from explicit to implicit is a loss of information, and has a
>> large impact on the language, it can't easily be undone, so it requires a
>> large discussion when it's decided. It only adds a little additional
>> convenience to the user though.
>>
>> I suggest we discuss implicit generation and allowing omission with
>> follow-up proposals, they will very likely be additive non-breaking
>> changes. For this proposal we play it safe and stick to explicit
>> conformance and no omission of fields.
>>
>>
>> On Fri, May 5, 2017 at 8:01 AM, Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> Hmm, I can see the appeal of automatically deriving Equatable and
>>> Hashable conformance, but I'd like that to be opt-in. That is, types should
>>> declare that they are Equatable or Hashable to begin with. It wouldn't have
>>> to take extra syntax, as compiler magic could effectively synthesize
>>> default implementations for == and/or hashValue when all members are
>>> themselves Equatable or Hashable, respectively. With such a scheme,
>>> consideration can be made to accommodating classes too.
>>> On Thu, May 4, 2017 at 15:37 Tony Allevato via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
 Hi all,

 A conversation on Twitter last night brought up some interest in this
 feature and I was encouraged to revive this proposal.

 Jordan Rose mentioned
  on Twitter
 that it could possibly make it in by the Swift 4 deadline if others
 contributed—I have a WIP branch (albeit not currently working because I
 rebased after a couple months of it being idle) that does the work for
 enums but I got stuck on the mutually recursive cases. If this got
 approved, I'd love to collaborate with other interested folks to finish up
 the implementation.

 Link: https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad


 Deriving Equatable and Hashable for value types

- Proposal: SE-

 
- Author(s): Tony Allevato 
- Status: Awaiting review

 
- Review manager: TBD


 

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

2017-05-04 Thread Andrew Bennett via swift-evolution
That's correct, consistent with Encoding/Decoding (SE-0166
)
it is sufficient to just do this:

struct MyType: Hashable {

  var foo: Int

  var bar: Float

}


Now MyType should get a generated implementation because each member is
also Hashable.


There's more details in the proposal near:

> An enum T that derives Equatable will receive a compiler-generated
> implementation of




On Fri, May 5, 2017 at 8:15 AM, Xiaodi Wu  wrote:

> I'm imagining no syntax; effectively, as though there exists an "extension
> Equatable where [ all members : Equatable ]" with a default implementation.
>
>
> On Thu, May 4, 2017 at 17:13 John McCall  wrote:
>
>> On May 4, 2017, at 6:10 PM, Andrew Bennett via swift-evolution <
>> swift-evolution@swift.org> wrote:
>> I agree, let's make it opt-in.
>>
>> This looks really great, I'm excited to get generated conformance for
>> Equatable/Hashable in time for Swift 4.
>>
>> I think it's worth mentioning that Encoding/Decoding generated
>> conformance is already accepted and implemented in Swift 4. The
>> implementation and acceptance criterion for Equatable/Hashable is likely to
>> be very similar.
>>
>> *For the open questions*, I think for the sake of getting this into
>> Swift 4 we should go for explicit derivation, and don't allow omission of
>> fields (yet).
>>
>>
>> Is there a syntax proposal for explicit derivation?  Or are you imagining
>> that just declaring the conformance but failing to implement it should
>> trigger derivation?
>>
>> John.
>>
>>
>> Omission is nice-to-have, but likely to be a long-winded bike-shed.
>>
>> Changing from explicit to implicit is a loss of information, and has a
>> large impact on the language, it can't easily be undone, so it requires a
>> large discussion when it's decided. It only adds a little additional
>> convenience to the user though.
>>
>> I suggest we discuss implicit generation and allowing omission with
>> follow-up proposals, they will very likely be additive non-breaking
>> changes. For this proposal we play it safe and stick to explicit
>> conformance and no omission of fields.
>>
>>
>> On Fri, May 5, 2017 at 8:01 AM, Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> Hmm, I can see the appeal of automatically deriving Equatable and
>>> Hashable conformance, but I'd like that to be opt-in. That is, types should
>>> declare that they are Equatable or Hashable to begin with. It wouldn't have
>>> to take extra syntax, as compiler magic could effectively synthesize
>>> default implementations for == and/or hashValue when all members are
>>> themselves Equatable or Hashable, respectively. With such a scheme,
>>> consideration can be made to accommodating classes too.
>>> On Thu, May 4, 2017 at 15:37 Tony Allevato via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
 Hi all,

 A conversation on Twitter last night brought up some interest in this
 feature and I was encouraged to revive this proposal.

 Jordan Rose mentioned
  on Twitter
 that it could possibly make it in by the Swift 4 deadline if others
 contributed—I have a WIP branch (albeit not currently working because I
 rebased after a couple months of it being idle) that does the work for
 enums but I got stuck on the mutually recursive cases. If this got
 approved, I'd love to collaborate with other interested folks to finish up
 the implementation.

 Link: https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad


 Deriving Equatable and Hashable for value types

- Proposal: SE-

 
- Author(s): Tony Allevato 
- Status: Awaiting review

 
- Review manager: TBD


 
 Introduction

 Value types are prevalent throughout the Swift language, and we
 encourage developers to think in those terms when writing their own types.
 Frequently, developers have to write large amounts of boilerplate code to
 support equatability and hashability of value types. This proposal offers a
 way for the compiler to automatically derive conformance to Equatable
 and Hashable to reduce this boilerplate, in a subset of scenarios
 where generating the correct implementation is known to be possible.

 Swift-evolution thread: Universal Equatability, Hashability, and
 Comparability
 

 

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

2017-05-04 Thread Xiaodi Wu via swift-evolution
I should add, requiring opt-in doesn't necessarily mean one must break
source compatibility for enums currently with derived equality. That can be
grandfathered in.

Later, we can even explore more comprehensive functionality when an enum is
declared "Foo : Int". In my opinion, the ideal endpoint in Swift N (where N
>> 4) is true value subtyping; absent that, it would only make sense that
Foo would at least conform to all the protocols to which Int conforms. A
longer-term discussion clearly out of scope here, but mentioned only to say
that existing magic doesn't need to be rolled back necessarily.

While we're on this topic though, it'd be really nice to revisit Equatable
and Hashable for tuples; that's one place where implicit magic may be the
best way to go. Currently, tuples of arity 6 or less benefit from a manual
hack to be Equatable, but we can clearly do better.

On Thu, May 4, 2017 at 17:01 Xiaodi Wu  wrote:

> Hmm, I can see the appeal of automatically deriving Equatable and Hashable
> conformance, but I'd like that to be opt-in. That is, types should declare
> that they are Equatable or Hashable to begin with. It wouldn't have to take
> extra syntax, as compiler magic could effectively synthesize default
> implementations for == and/or hashValue when all members are themselves
> Equatable or Hashable, respectively. With such a scheme, consideration can
> be made to accommodating classes too.
> On Thu, May 4, 2017 at 15:37 Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> Hi all,
>>
>> A conversation on Twitter last night brought up some interest in this
>> feature and I was encouraged to revive this proposal.
>>
>> Jordan Rose mentioned
>>  on Twitter that
>> it could possibly make it in by the Swift 4 deadline if others
>> contributed—I have a WIP branch (albeit not currently working because I
>> rebased after a couple months of it being idle) that does the work for
>> enums but I got stuck on the mutually recursive cases. If this got
>> approved, I'd love to collaborate with other interested folks to finish up
>> the implementation.
>>
>> Link: https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad
>>
>>
>> Deriving Equatable and Hashable for value types
>>
>>- Proposal: SE-
>>
>> 
>>- Author(s): Tony Allevato 
>>- Status: Awaiting review
>>
>> 
>>- Review manager: TBD
>>
>>
>> 
>> Introduction
>>
>> Value types are prevalent throughout the Swift language, and we encourage
>> developers to think in those terms when writing their own types.
>> Frequently, developers have to write large amounts of boilerplate code to
>> support equatability and hashability of value types. This proposal offers a
>> way for the compiler to automatically derive conformance to Equatable and
>>  Hashable to reduce this boilerplate, in a subset of scenarios where
>> generating the correct implementation is known to be possible.
>>
>> Swift-evolution thread: Universal Equatability, Hashability, and
>> Comparability
>> 
>>
>> 
>> Motivation
>>
>> Building robust value types in Swift can involve writing significant
>> boilerplate code to support hashability and equatability. Equality is
>> pervasive across many value types, and for each one users must implement the
>>  == operator such that it performs a fairly rote memberwise equality
>> test. As an example, an equality test for a struct looks fairly
>> uninteresting:
>>
>> struct Foo: Equatable {
>>   static func == (lhs: Foo, rhs: Foo) -> Bool {
>> return lhs.property1 == rhs.property1 &&
>>lhs.property2 == rhs.property2 &&
>>lhs.property3 == rhs.property3 &&
>>...
>>   }
>> }
>>
>> What's worse is that this operator must be updated if any properties are
>> added, removed, or changed, and since it must be manually written, it's
>> possible to get it wrong, either by omission or typographical error.
>>
>> Likewise, hashability is necessary when one wishes to store a value type
>> in a Set or use one as a multi-valued Dictionary key. Writing
>> high-quality, well-distributed hash functions is not trivial so developers
>> may not put a great deal of thought into them – especially as the number of
>> properties increases – not realizing that their performance could
>> potentially suffer as a result. And as with equality, writing it manually
>> means there is the potential to get it wrong.
>>
>> In particular, the code that must be written to implement equality for
>> enums is quite verbose:
>>
>> 

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

2017-05-04 Thread Xiaodi Wu via swift-evolution
I'm imagining no syntax; effectively, as though there exists an "extension
Equatable where [ all members : Equatable ]" with a default implementation.


On Thu, May 4, 2017 at 17:13 John McCall  wrote:

> On May 4, 2017, at 6:10 PM, Andrew Bennett via swift-evolution <
> swift-evolution@swift.org> wrote:
> I agree, let's make it opt-in.
>
> This looks really great, I'm excited to get generated conformance for
> Equatable/Hashable in time for Swift 4.
>
> I think it's worth mentioning that Encoding/Decoding generated conformance
> is already accepted and implemented in Swift 4. The implementation and
> acceptance criterion for Equatable/Hashable is likely to be very similar.
>
> *For the open questions*, I think for the sake of getting this into Swift
> 4 we should go for explicit derivation, and don't allow omission of fields
> (yet).
>
>
> Is there a syntax proposal for explicit derivation?  Or are you imagining
> that just declaring the conformance but failing to implement it should
> trigger derivation?
>
> John.
>
>
> Omission is nice-to-have, but likely to be a long-winded bike-shed.
>
> Changing from explicit to implicit is a loss of information, and has a
> large impact on the language, it can't easily be undone, so it requires a
> large discussion when it's decided. It only adds a little additional
> convenience to the user though.
>
> I suggest we discuss implicit generation and allowing omission with
> follow-up proposals, they will very likely be additive non-breaking
> changes. For this proposal we play it safe and stick to explicit
> conformance and no omission of fields.
>
>
> On Fri, May 5, 2017 at 8:01 AM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> Hmm, I can see the appeal of automatically deriving Equatable and
>> Hashable conformance, but I'd like that to be opt-in. That is, types should
>> declare that they are Equatable or Hashable to begin with. It wouldn't have
>> to take extra syntax, as compiler magic could effectively synthesize
>> default implementations for == and/or hashValue when all members are
>> themselves Equatable or Hashable, respectively. With such a scheme,
>> consideration can be made to accommodating classes too.
>> On Thu, May 4, 2017 at 15:37 Tony Allevato via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> Hi all,
>>>
>>> A conversation on Twitter last night brought up some interest in this
>>> feature and I was encouraged to revive this proposal.
>>>
>>> Jordan Rose mentioned
>>>  on Twitter
>>> that it could possibly make it in by the Swift 4 deadline if others
>>> contributed—I have a WIP branch (albeit not currently working because I
>>> rebased after a couple months of it being idle) that does the work for
>>> enums but I got stuck on the mutually recursive cases. If this got
>>> approved, I'd love to collaborate with other interested folks to finish up
>>> the implementation.
>>>
>>> Link: https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad
>>>
>>>
>>> Deriving Equatable and Hashable for value types
>>>
>>>- Proposal: SE-
>>>
>>> 
>>>- Author(s): Tony Allevato 
>>>- Status: Awaiting review
>>>
>>> 
>>>- Review manager: TBD
>>>
>>>
>>> 
>>> Introduction
>>>
>>> Value types are prevalent throughout the Swift language, and we
>>> encourage developers to think in those terms when writing their own types.
>>> Frequently, developers have to write large amounts of boilerplate code to
>>> support equatability and hashability of value types. This proposal offers a
>>> way for the compiler to automatically derive conformance to Equatable
>>> and Hashable to reduce this boilerplate, in a subset of scenarios where
>>> generating the correct implementation is known to be possible.
>>>
>>> Swift-evolution thread: Universal Equatability, Hashability, and
>>> Comparability
>>> 
>>>
>>> 
>>> Motivation
>>>
>>> Building robust value types in Swift can involve writing significant
>>> boilerplate code to support hashability and equatability. Equality is
>>> pervasive across many value types, and for each one users must implement the
>>>  == operator such that it performs a fairly rote memberwise equality
>>> test. As an example, an equality test for a struct looks fairly
>>> uninteresting:
>>>
>>> struct Foo: Equatable {
>>>   static func == (lhs: Foo, rhs: Foo) -> Bool {
>>> return lhs.property1 == rhs.property1 &&
>>>lhs.property2 == rhs.property2 &&
>>>lhs.property3 == rhs.property3 &&
>>>

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

2017-05-04 Thread Andrew Bennett via swift-evolution
I agree, let's make it opt-in.

This looks really great, I'm excited to get generated conformance for
Equatable/Hashable in time for Swift 4.

I think it's worth mentioning that Encoding/Decoding generated conformance
is already accepted and implemented in Swift 4. The implementation and
acceptance criterion for Equatable/Hashable is likely to be very similar.

*For the open questions*, I think for the sake of getting this into Swift 4
we should go for explicit derivation, and don't allow omission of fields
(yet).

Omission is nice-to-have, but likely to be a long-winded bike-shed.

Changing from explicit to implicit is a loss of information, and has a
large impact on the language, it can't easily be undone, so it requires a
large discussion when it's decided. It only adds a little additional
convenience to the user though.

I suggest we discuss implicit generation and allowing omission with
follow-up proposals, they will very likely be additive non-breaking
changes. For this proposal we play it safe and stick to explicit
conformance and no omission of fields.


On Fri, May 5, 2017 at 8:01 AM, Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:

> Hmm, I can see the appeal of automatically deriving Equatable and Hashable
> conformance, but I'd like that to be opt-in. That is, types should declare
> that they are Equatable or Hashable to begin with. It wouldn't have to take
> extra syntax, as compiler magic could effectively synthesize default
> implementations for == and/or hashValue when all members are themselves
> Equatable or Hashable, respectively. With such a scheme, consideration can
> be made to accommodating classes too.
> On Thu, May 4, 2017 at 15:37 Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> Hi all,
>>
>> A conversation on Twitter last night brought up some interest in this
>> feature and I was encouraged to revive this proposal.
>>
>> Jordan Rose mentioned
>>  on Twitter that
>> it could possibly make it in by the Swift 4 deadline if others
>> contributed—I have a WIP branch (albeit not currently working because I
>> rebased after a couple months of it being idle) that does the work for
>> enums but I got stuck on the mutually recursive cases. If this got
>> approved, I'd love to collaborate with other interested folks to finish up
>> the implementation.
>>
>> Link: https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad
>>
>>
>> Deriving Equatable and Hashable for value types
>>
>>- Proposal: SE-
>>
>> 
>>- Author(s): Tony Allevato 
>>- Status: Awaiting review
>>
>> 
>>- Review manager: TBD
>>
>>
>> 
>> Introduction
>>
>> Value types are prevalent throughout the Swift language, and we encourage
>> developers to think in those terms when writing their own types.
>> Frequently, developers have to write large amounts of boilerplate code to
>> support equatability and hashability of value types. This proposal offers a
>> way for the compiler to automatically derive conformance to Equatable and
>>  Hashable to reduce this boilerplate, in a subset of scenarios where
>> generating the correct implementation is known to be possible.
>>
>> Swift-evolution thread: Universal Equatability, Hashability, and
>> Comparability
>> 
>>
>> 
>> Motivation
>>
>> Building robust value types in Swift can involve writing significant
>> boilerplate code to support hashability and equatability. Equality is
>> pervasive across many value types, and for each one users must implement the
>>  == operator such that it performs a fairly rote memberwise equality
>> test. As an example, an equality test for a struct looks fairly
>> uninteresting:
>>
>> struct Foo: Equatable {
>>   static func == (lhs: Foo, rhs: Foo) -> Bool {
>> return lhs.property1 == rhs.property1 &&
>>lhs.property2 == rhs.property2 &&
>>lhs.property3 == rhs.property3 &&
>>...
>>   }
>> }
>>
>> What's worse is that this operator must be updated if any properties are
>> added, removed, or changed, and since it must be manually written, it's
>> possible to get it wrong, either by omission or typographical error.
>>
>> Likewise, hashability is necessary when one wishes to store a value type
>> in a Set or use one as a multi-valued Dictionary key. Writing
>> high-quality, well-distributed hash functions is not trivial so developers
>> may not put a great deal of thought into them – especially as the number of
>> properties increases – not realizing that their performance could
>> 

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

2017-05-04 Thread Xiaodi Wu via swift-evolution
Hmm, I can see the appeal of automatically deriving Equatable and Hashable
conformance, but I'd like that to be opt-in. That is, types should declare
that they are Equatable or Hashable to begin with. It wouldn't have to take
extra syntax, as compiler magic could effectively synthesize default
implementations for == and/or hashValue when all members are themselves
Equatable or Hashable, respectively. With such a scheme, consideration can
be made to accommodating classes too.
On Thu, May 4, 2017 at 15:37 Tony Allevato via swift-evolution <
swift-evolution@swift.org> wrote:

> Hi all,
>
> A conversation on Twitter last night brought up some interest in this
> feature and I was encouraged to revive this proposal.
>
> Jordan Rose mentioned
>  on Twitter that
> it could possibly make it in by the Swift 4 deadline if others
> contributed—I have a WIP branch (albeit not currently working because I
> rebased after a couple months of it being idle) that does the work for
> enums but I got stuck on the mutually recursive cases. If this got
> approved, I'd love to collaborate with other interested folks to finish up
> the implementation.
>
> Link: https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad
>
>
> Deriving Equatable and Hashable for value types
>
>- Proposal: SE-
>
> 
>- Author(s): Tony Allevato 
>- Status: Awaiting review
>
> 
>- Review manager: TBD
>
>
> 
> Introduction
>
> Value types are prevalent throughout the Swift language, and we encourage
> developers to think in those terms when writing their own types.
> Frequently, developers have to write large amounts of boilerplate code to
> support equatability and hashability of value types. This proposal offers a
> way for the compiler to automatically derive conformance to Equatable and
> Hashable to reduce this boilerplate, in a subset of scenarios where
> generating the correct implementation is known to be possible.
>
> Swift-evolution thread: Universal Equatability, Hashability, and
> Comparability
> 
>
> 
> Motivation
>
> Building robust value types in Swift can involve writing significant
> boilerplate code to support hashability and equatability. Equality is
> pervasive across many value types, and for each one users must implement the
>  == operator such that it performs a fairly rote memberwise equality
> test. As an example, an equality test for a struct looks fairly
> uninteresting:
>
> struct Foo: Equatable {
>   static func == (lhs: Foo, rhs: Foo) -> Bool {
> return lhs.property1 == rhs.property1 &&
>lhs.property2 == rhs.property2 &&
>lhs.property3 == rhs.property3 &&
>...
>   }
> }
>
> What's worse is that this operator must be updated if any properties are
> added, removed, or changed, and since it must be manually written, it's
> possible to get it wrong, either by omission or typographical error.
>
> Likewise, hashability is necessary when one wishes to store a value type
> in a Set or use one as a multi-valued Dictionary key. Writing
> high-quality, well-distributed hash functions is not trivial so developers
> may not put a great deal of thought into them – especially as the number of
> properties increases – not realizing that their performance could
> potentially suffer as a result. And as with equality, writing it manually
> means there is the potential to get it wrong.
>
> In particular, the code that must be written to implement equality for
> enums is quite verbose:
>
> enum Token: Equatable {
>   case string(String)
>   case number(Int)
>   case lparen
>   case rparen
>
>   static func == (lhs: Token, rhs: Token) -> Bool {
> switch (lhs, rhs) {
> case (.string(let lhsString), .string(let rhsString)):
>   return lhsString == rhsString
> case (.number(let lhsNumber), .number(let lhsNumber)):
>   return lhsNumber == rhsNumber
> case (.lparen, .lparen), (.rparen, .rparen):
>   return true
> default:
>   return false
> }
>   }
> }
>
> Crafting a high-quality hash function for this enum would be similarly
> inconvenient to write.
>
> Swift already derives Equatable and Hashable conformance for a small
> subset of enums: those for which the cases have no associated values
> (including enums with raw types). Two instances of such an enum are equal
> if they are the same case, and an instance's hash value is its ordinal:
>
> enum Foo  {
>   case zero, one, two
> }
> let x = (Foo.one == Foo.two)  // evaluates to falselet y = Foo.one.hashValue  
>// evaluates to 1
>
> 

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

2017-05-04 Thread Tony Allevato via swift-evolution
Hi all,

A conversation on Twitter last night brought up some interest in this
feature and I was encouraged to revive this proposal.

Jordan Rose mentioned
 on Twitter that it
could possibly make it in by the Swift 4 deadline if others contributed—I
have a WIP branch (albeit not currently working because I rebased after a
couple months of it being idle) that does the work for enums but I got
stuck on the mutually recursive cases. If this got approved, I'd love to
collaborate with other interested folks to finish up the implementation.

Link: https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad


Deriving Equatable and Hashable for value types

   - Proposal: SE-
   
   - Author(s): Tony Allevato 
   - Status: Awaiting review
   
   - Review manager: TBD


Introduction

Value types are prevalent throughout the Swift language, and we encourage
developers to think in those terms when writing their own types.
Frequently, developers have to write large amounts of boilerplate code to
support equatability and hashability of value types. This proposal offers a
way for the compiler to automatically derive conformance to Equatable and
Hashable to reduce this boilerplate, in a subset of scenarios where
generating the correct implementation is known to be possible.

Swift-evolution thread: Universal Equatability, Hashability, and
Comparability 

Motivation

Building robust value types in Swift can involve writing significant
boilerplate code to support hashability and equatability. Equality is
pervasive across many value types, and for each one users must implement the
 == operator such that it performs a fairly rote memberwise equality test.
As an example, an equality test for a struct looks fairly uninteresting:

struct Foo: Equatable {
  static func == (lhs: Foo, rhs: Foo) -> Bool {
return lhs.property1 == rhs.property1 &&
   lhs.property2 == rhs.property2 &&
   lhs.property3 == rhs.property3 &&
   ...
  }
}

What's worse is that this operator must be updated if any properties are
added, removed, or changed, and since it must be manually written, it's
possible to get it wrong, either by omission or typographical error.

Likewise, hashability is necessary when one wishes to store a value type in
a Set or use one as a multi-valued Dictionary key. Writing high-quality,
well-distributed hash functions is not trivial so developers may not put a
great deal of thought into them – especially as the number of properties
increases – not realizing that their performance could potentially suffer
as a result. And as with equality, writing it manually means there is the
potential to get it wrong.

In particular, the code that must be written to implement equality for
enums is quite verbose:

enum Token: Equatable {
  case string(String)
  case number(Int)
  case lparen
  case rparen

  static func == (lhs: Token, rhs: Token) -> Bool {
switch (lhs, rhs) {
case (.string(let lhsString), .string(let rhsString)):
  return lhsString == rhsString
case (.number(let lhsNumber), .number(let lhsNumber)):
  return lhsNumber == rhsNumber
case (.lparen, .lparen), (.rparen, .rparen):
  return true
default:
  return false
}
  }
}

Crafting a high-quality hash function for this enum would be similarly
inconvenient to write.

Swift already derives Equatable and Hashable conformance for a small subset
of enums: those for which the cases have no associated values (including
enums with raw types). Two instances of such an enum are equal if they are
the same case, and an instance's hash value is its ordinal:

enum Foo  {
  case zero, one, two
}
let x = (Foo.one == Foo.two)  // evaluates to falselet y =
Foo.one.hashValue // evaluates to 1

Likewise, conformance to RawRepresentable is automatically derived for
enums with a raw type. Since there is precedent for derived conformances in
Swift, we propose extending this support to more value types.
Proposed
solution

In general, we propose that value types derive conformance to Equatable/
Hashable if all of its members are Equatable/Hashable. We describe the
specific conditions under which these conformances are derived below,
followed by the details of how the conformance requirements are implemented.
Protocol
derivability conditions

For brevity, let P represent either the protocol