> On Sep 7, 2017, at 1:43 PM, Haravikk via swift-evolution 
> <[email protected]> wrote:
> 
>> 
>> On 7 Sep 2017, at 19:36, Tony Allevato <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> 
>> 
>> On Thu, Sep 7, 2017 at 11:18 AM Haravikk via swift-evolution 
>> <[email protected] <mailto:[email protected]>> wrote:
>> 
>>> On 7 Sep 2017, at 18:53, Tony Allevato via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> 
>>> 
>>> 
>>> On Thu, Sep 7, 2017 at 10:39 AM Gwendal Roué <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>>> Le 7 sept. 2017 à 14:45, Tony Allevato <[email protected] 
>>>> <mailto:[email protected]>> a écrit :
>>>> 
>>>> Right, let's make sure we're talking about the right thing here. Gwendal, 
>>>> your issue isn't with synthesis in the form of Codable or the new 
>>>> additions to Equatable/Hashable which are opt-in-by-conformance, it's with 
>>>> the specific case of raw value enums or enums without associated values 
>>>> where the synthesis is implicit with no way to opt-out. That's a big 
>>>> difference.
>>> 
>>> Yes.
>>> 
>>>> I can definitely see the latter being an issue if it were more widespread, 
>>>> and I'd be supportive of those enums being required to declare their 
>>>> conformance for consistency (though it would be source breaking).
>>> 
>>> Yes, unfortunately.
>>> 
>>> 
>>>> However, I still haven't seen a real issue that has come up because of the 
>>>> distinction being drawn here between default implementations vs. 
>>>> implementations that can access other parts of the concrete type. It 
>>>> sounds like this discussion is trying to protect against a hypothetical 
>>>> problem that hasn't happened yet and may not happen; it would be helpful 
>>>> to show some motivating real-world cases where this is indeed a severe 
>>>> problem.
>>> 
>>> Yes. I'm not talking about implementation itself. I know this has been the 
>>> main topic until I have tried to bring in the topic of the consequences of 
>>> non-avoidable synthesis (extra methods that may conflict with userland 
>>> methods).
>>> 
>>> If you ask me for a real-world case, then I think I gave one. Let me 
>>> rephrase it:
>>> 
>>> it's impossible to define a value-backed enum without getting free 
>>> Equatable conformance. This free conformance is sometimes unwanted, and I 
>>> gave the example of DSLs. Now this problem is not *severe*. It's more a 
>>> blind spot in the language, and finally just an unwanted side-effect of a 
>>> compiler convenience,
>>> 
>>> Again, this is not the issue that Haravikk is describing in this thread.
>>> 
>>> I'll clarify—your issue is specifically with the fact that enums with raw 
>>> values and enums without associated values receive Equatable even without 
>>> explicitly conforming to it, and therefore users have no way of opting out 
>>> of it. This predates SE-0185, and I didn't propose making any changes to 
>>> the conformance of those enums for source compatibility reasons, though I 
>>> wouldn't be opposed to it because it makes them consistent across the board.
>>> 
>>> Haravikk's argument is about synthesized conformances like Codable and 
>>> Equatable/Hashable in SE-0185, where the user must explicitly conform the 
>>> type to those protocols. His claim is that that act of opting in is not 
>>> sufficient and that it is still dangerous if those synthesized conformances 
>>> can access members that are not also declared in the protocol. That's a 
>>> completely separate issue to yours, and one that I hope he'll present more 
>>> evidence of. Right now, requiring that you not only explicitly conform to 
>>> the protocol but also explicitly request the synthesis feels like a 
>>> solution without an actual problem, and is a situation we already have 
>>> today with default method implementations.
>> 
>> The simplest real-world case is easy:
>> 
>>      struct Foo { var data:String }
>>      extension Foo : Equatable {} // This currently produces an error, in 
>> future it will not
>> 
>> 
>> Why is this a problem? It's no different than if someone extended Foo to 
>> conform to a protocol with a default implementation that was written in code.
> 
> I'm sorry but I have now explained why it isn't multiple times; a 
> non-reflective default conformance can ONLY act upon methods and properties 
> that the protocol itself has defined, meaning that it knows everything it 
> needs to know in order to do whatever it wants to do with those methods and 
> properties because it defined them.
Just because it might have defined the properties does not necessarily mean 
that those properties are sufficient context for providing a default 
implementation:
protocol Fooable : Equatable { // Equatable is just a simple example
    var myFoo: Int { get }
}

extension Fooable {
    static func ==(_ lhs: Self, _ rhs: Self) -> Bool {
        return lhs.myFoo == rhs.myFoo
    }
}

struct X : Fooable {
    let myFoo: Int
    let myName: String
    // Whoops, forgot to give an implementation of ==
}

print(X(myFoo: 42, myName: "Alice") == X(myFoo: 42, myName: "Bob")) // true
This property is necessary, but not sufficient to provide a correct 
implementation. A default implementation might be able to assume something 
about the types that it defines, but it does not necessarily know enough.

> Reflective/synthesised default implementations must by their very nature make 
> assumptions about a concrete type that are not cannot be guaranteed to be 
> correct. The properties and methods they may end up interacting with may have 
> nothing at all to do with the protocol. Equatable remains by far the simplest 
> example; just because a developer has used equatable properties does not 
> guarantee that all of them should be compared during a check for equality.
In the same way that you might consider synthesized conformances to overreach 
into a type and touch things which are not related to a protocol, default 
implementations can be considered underreach in that they don’t know anything 
about properties which are necessary for providing a correct implementation.

> These things are two very different beasts.
I think they’re very much two sides of the same coin.

> While a developer may wish to override a default implementation, it should 
> only be to provide optimisations that a protocol cannot; e.g- providing a 
> logarithmic time search to replace to a linear time search. The end result 
> however should be the same; i.e- there is no change in behaviour, only detail.
> 
> A synthesised/reflective implementation however may return a result that is 
> simply incorrect, because it is based on assumptions made by the protocol 
> developer, with no input from the developer of the concrete type. In this 
> case the developer must override it in to provide correct behaviour.
> 
>> That's not a fair characterization. Just because your concerns were 
>> disagreed with does not mean they were ignored; my understanding is that the 
>> core team views these synthesized conformances as a different kind of 
>> default method (and one which could be hoisted out of the compiler once 
>> sufficient metaprogramming facilities are available).
>> 
>> The way to handle synthesized conformances was discussed during the review 
>> period for Codable, during the earlier pitch a few months ago for what 
>> became SE-0185, and again during its formal review. It's not accurate to 
>> reduce the argument you disagree with to "but Codable does it" when what 
>> you're referring to is established precedent based on those prior 
>> discussions.
> 
> If that is the case then surely someone, including members of the core team, 
> could have easily summarised what the rationale behind that was and why they 
> think it applies to Equatable/Hashable. They did not, hence, ignored. I even 
> framed my argument purely on the basis of why the Equatable/Hashable case 
> differs from Codable and still nothing. It is absolutely fair for me to 
> characterise that as being ignored.
> 
>> I feel like we keep going back to this, but this statement applies equally 
>> to non-synthesized default implementations. Are you suggesting that users 
>> should have to opt-in specifically to all default implementations provided 
>> by a protocol in some way beyond merely conforming to that protocol? If not, 
>> what specifically makes synthesized conformances a special case?
> 
> As mentioned, this is a special case because the behaviour being provided is 
> not constrained to the protocol that provides it; it is invasive of a 
> concrete type, and by its very nature can potentially produce incorrect 
> results.
> _______________________________________________
> swift-evolution mailing list
> [email protected] <mailto:[email protected]>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to