All right, I'll be more positive: our science, IT, is a *constructive* science, 
by *essence*. If there is a problem, there must be a way to show it.

It you can't, then there is no problem.

Gwendal

> Le 9 sept. 2017 à 15:26, Gwendal Roué <[email protected]> a écrit :
> 
> Hello Haravikk,
> 
> I'lm worried that you fail at preventing a real problem. May I suggest a 
> change in your strategy?
> 
> Sometimes, sample code greatly helps turning subtle ideas into blatant 
> evidence. After all, subtleties are all about corner cases, and corner cases 
> are the blind spots of imagination. What about giving that little something 
> that would help your readers grasp your arguments?
> 
> I don't quite know what example you will provide, but I could suggest the 
> exhibition of a practical problem with Equatable synthesis. We'll know better 
> if the problem can arise in the Standard lib, in third-party libraries, at 
> application level, or at several scales at the same time. It would also be 
> nice to see your solution to the problem, that is to say an alternative that 
> still provides code synthesis for developers that want to opt in the feature, 
> but avoids the caveat of the initial example. I hope this would greatly help 
> the discussion move forward.
> 
> Last general comment about the topic: if Haravikk is right, and that code 
> synthesis should indeed be explicit, then that wouldn't be such a shame.
> 
> My two cents,
> Gwendal Roué
> 
> 
>> Le 9 sept. 2017 à 13:41, Haravikk via swift-evolution 
>> <[email protected] <mailto:[email protected]>> a écrit :
>> 
>>> 
>>> On 9 Sep 2017, at 09:33, Xiaodi Wu <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>> 
>>> On Sat, Sep 9, 2017 at 02:47 Haravikk via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> 
>>>> On 9 Sep 2017, at 02:02, Xiaodi Wu <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>> 
>>>> On Fri, Sep 8, 2017 at 4:00 PM, Itai Ferber via swift-evolution 
>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>> 
>>>> 
>>>>> On Sep 8, 2017, at 12:46 AM, Haravikk via swift-evolution 
>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>> 
>>>>> 
>>>>>> On 7 Sep 2017, at 22:02, Itai Ferber <[email protected] 
>>>>>> <mailto:[email protected]>> wrote:
>>>>>> 
>>>>>> 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.
>>>>> 
>>>>> Sorry but that's a bit of a contrived example; in this case the protocol 
>>>>> should not implement the equality operator if more information may be 
>>>>> required to define equality. It should only be implemented if the 
>>>>> protocol is absolutely clear that .myFoo is the only part of a Fooable 
>>>>> that can or should be compared as equatable, e.g- if a Fooable is a 
>>>>> database record and .myFoo is a primary key, the data could differ but it 
>>>>> would still be a reference to the same record.
>>>>> 
>>>>> To be clear, I'm not arguing that someone can't create a regular default 
>>>>> implementation that also makes flawed assumptions, but that 
>>>>> synthesised/reflective implementations by their very nature have to, as 
>>>>> they cannot under every circumstance guarantee correctness when using 
>>>>> parts of a concrete type that they know nothing about.
>>>> 
>>>> You can’t argue this both ways:
>>>> If you’re arguing this on principle, that in order for synthesized 
>>>> implementations to be correct, they must be able to — under every 
>>>> circumstance — guarantee correctness, then you have to apply the same 
>>>> reasoning to default protocol implementations. Given a default protocol 
>>>> implementation, it is possible to come up with a (no matter how contrived) 
>>>> case where the default implementation is wrong. Since you’re arguing this 
>>>> on principle, you cannot reject contrived examples.
>>>> If you are arguing this in practice, then you’re going to have to back up 
>>>> your argument with evidence that synthesized examples are more often wrong 
>>>> than default implementations. You can’t declare that synthesized 
>>>> implementations are by nature incorrect but allow default implementations 
>>>> to slide because in practice, many implementations are allowable. There’s 
>>>> a reason why synthesis passed code review and was accepted: in the 
>>>> majority of cases, synthesis was deemed to be beneficial, and would 
>>>> provide correct behavior. If you are willing to say that yes, sometimes 
>>>> default implementations are wrong but overall they’re correct, you’re 
>>>> going to have to provide hard evidence to back up the opposite case for 
>>>> synthesized implementations. You stated in a previous email that "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." — if 
>>>> you can back this up with evidence (say, taking a survey of a large number 
>>>> of model types and see if in the majority of cases synthesized 
>>>> implementation would be incorrect) to provide a compelling argument, then 
>>>> this is something that we should in that case reconsider.
>>>> 
>>>> Well put, and I agree with this position 100%. However, to play devil's 
>>>> advocate here, let me summarize what I think Haravikk is saying:
>>>> 
>>>> I think the "synthesized" part of this is a red herring, if I understand 
>>>> Haravikk's argument correctly. Instead, it is this:
>>>> 
>>>> (1) In principle, it is possible to have a default implementation for a 
>>>> protocol requirement that produces the correct result--though not 
>>>> necessarily in the most performant way--for all possible conforming types, 
>>>> where by conforming we mean that the type respects both the syntactic 
>>>> requirements (enforced by the compiler) and the semantic requirements 
>>>> (which may not necessarily be enforceable by the compiler) of the protocol 
>>>> in question.
>>>> 
>>>> (2) However, there exist *some* requirements that, by their very nature, 
>>>> cannot have default implementations which are guaranteed to produce the 
>>>> correct result for all conforming types. In Haravikk's view, no default 
>>>> implementations should be provided in these cases. (I don't necessarily 
>>>> subscribe to this view in absolute terms, but for the sake of argument 
>>>> let's grant this premise.)
>>>> 
>>>> (3) Equatable, Hashable, and Codable requirements are, by their very 
>>>> nature, such requirements that cannot have default implementations 
>>>> guaranteed to be correct for all conforming types. Therefore, they should 
>>>> not have a default implementation. It just so happens that a default 
>>>> implementation cannot currently be written in Swift itself and must be 
>>>> synthesized, but Haravikk's point is that even if they could be written in 
>>>> native Swift through a hypothetical reflection facility, they should not 
>>>> be, just as many other protocol requirements currently could have default 
>>>> implementations written in Swift but should not have them because they 
>>>> cannot be guaranteed to produce the correct result.
>>>> 
>>>> My response to this line of argumentation is as follows:
>>>> 
>>>> For any open protocol (i.e., a protocol for which the universe of possible 
>>>> conforming types cannot be enumerated a priori by the protocol designer) 
>>>> worthy of being a protocol by the Swift standard ("what useful thing can 
>>>> you do with such a protocol that you could not without?"), any 
>>>> sufficiently interesting requirement (i.e., one for which user ergonomics 
>>>> would measurably benefit from a default implementation) either cannot have 
>>>> a universally guaranteed correct implementation or has an implementation 
>>>> which is also going to be the most performant one (which can therefore be 
>>>> a non-overridable protocol extension method rather than an overridable 
>>>> protocol requirement with a default implementation). 
>>> 
>>> You're close, but still missing key points:
>>> 
>>> I am not arguing that features like these should not be provided, but that 
>>> they should not be provided implicitly, and that the developer should 
>>> actually be allowed to request them. That is exactly what this proposal is 
>>> about, yet no matter what I say everyone seems to be treating me like I'm 
>>> against these features entirely; I am not.
>>> 
>>> You are entirely against Equatable having a default implementation for ==. 
>>> This is unequivocally stated. Others favor such a default implementation 
>>> and feel that in the absence of a way to spell this in Swift itself, it 
>>> should be magic for the time being. For the purposes of this argument it 
>>> really is not pertinent that you are not also against something else; 
>>> you're asking us to discuss why you are against a particular thing that 
>>> others are for.
>> 
>> FFS, how much clearer can I make this? I AM NOT AGAINST THE FEATURE.
>> 
>> What I am against is the way in which it is being provided implicitly rather 
>> than explicitly, in particular as a retroactive change to existing protocols 
>> in a way that introduces potential for bugs that are currently impossible, 
>> but also in general.
>> 
>>> As repeatedly answered by others, nothing here is specific to synthesized 
>>> default implementations, as more powerful reflection will gradually allow 
>>> them to be non-synthesised.
>> 
>> And as repeatedly stated by me; I am not treating synthesised vs. run-time 
>> reflection any differently, I specifically included both in the original 
>> proposal.
>> 
>>> As pointed out very cogently by Itai, you assert but offer no evidence, 
>>> either in principle or empirically, that going too far by reflection is 
>>> worse than going not far enough without reflection in terms of likelihood 
>>> of a default implementation being inappropriate for conforming types.
>> 
>> As I have also repeatedly pointed out it is not an issue of "not going far 
>> enough" vs. "going too far"; if a default implementation lacks information 
>> then it should not be provided, doing so regardless is a flaw in the 
>> protocol design and not something that this proposal attempts to address (as 
>> such a thing is likely impossible).
>> 
>> Reflective implementations necessarily go too far, because they literally 
>> know nothing about the concrete type with any certainty, except for the 
>> properties that are defined in the protocol (which do not require reflection 
>> or synthesis in the first place).
>> 
>> And precisely what kind of "evidence" am I expected to give? This is a set 
>> of features that do not exist yet, I am trying to argue in favour of an 
>> explicit end-developer centric opt-in rather than an implicit protocol 
>> designer centric one. Yet no-one seems interested in the merits of allowing 
>> developers to choose what they want, rather than having implicit behaviours 
>> appear potentially unexpectedly.
>> 
>>> Therefore, your argument reduces to one about which default implementations 
>>> generally ought or ought not to be provided--that is, that they ought to be 
>>> provided only when their correctness can be guaranteed for all (rather than 
>>> almost all) possible conforming types. To which point I sketched a rebuttal 
>>> above.
>> 
>> If a protocol defines something, and creates a default implementation based 
>> only upon those definitions then it must by its very nature be correct. A 
>> concrete type may later decided to go further, but that is a feature of the 
>> concrete type, not a failure of the protocol itself which can function 
>> correctly within the context it created. You want to talk evidence, yet 
>> there has been no example given that proves otherwise; thus far only Itai 
>> has attempted to do so, but I have already pointed out the flaws with that 
>> example.
>> 
>> The simple fact is that a default implementation may either be flawed or not 
>> within the context of the protocol itself; but a reflective or synthetic 
>> implementation by its very nature goes beyond what the protocol defines and 
>> so is automatically flawed because as it does not rely on the end-developer 
>> to confirm correctness, not when provided implicitly at least.
>> 
>>> And all of this continues to be a side-issue to the fact that in the 
>>> specific case of Equatable/Hashable, which thus far has gone ignored, is 
>>> that bolting this on retroactively to an existing protocol hides bugs. The 
>>> issue of reflective default implementations is less of a concern on very 
>>> clearly and well defined new protocols, though I still prefer more, rather 
>>> than less, control, but in the specific case of existing protocols this 
>>> fucking about with behaviours is reckless and foolish in the extreme, yet 
>>> no-one on the core teams seems willing or able to justify it, which only 
>>> opens much wider concerns (how am I to have any faith in Swift's 
>>> development if the core team can't or won't justify the creation of new 
>>> bugs?).
>>> 
>>> This has emphatically not gone ignored, as I have myself responded to this 
>>> point in an earlier thread in which you commented, as well as many others. 
>>> Crucially, no existing conforming type changes its behavior, as they have 
>>> all had to implement these requirements themselves. And as I said to you 
>>> already, the addition of a synthesized default implementation no more 
>>> "hides bugs" going forward than the addition of a non-synthesized default 
>>> implementation to an existing protocol, and we do that with some frequency 
>>> without even Swift Evolution review.
>> 
>> Feel free to a supply a non-synthesised default implementation for Equatable 
>> without the use of reflection. Go-on, I'll wait.
>> You insist on suggesting these are the same thing, yet if you can't provide 
>> one then clearly they are not.
>> 
>>> Put another way, what the proposal about synthesizing implementations for 
>>> Equatable and Hashable was about can be thought of in two parts: (a) should 
>>> there be default implementations; and (b) given that it is impossible to 
>>> write these in Swift, should we use magic? Now, as I said above, adding 
>>> default implementations isn't (afaik) even considered an API change that 
>>> requires review on this list. Really, what people were debating was (b), 
>>> whether it is worth it to implement compiler-supported magic to make these 
>>> possible. Your disagreement has to do with (a) and not (b).
>> 
>> Wrong. The use of magic in this case produces something else entirely; 
>> that's the whole point. It is not the same, otherwise it wouldn't be needed 
>> at all. It doesn't matter if it's compiler magic, some external script or a 
>> native macro, ultimately they are all doing something with a concrete type 
>> that is currently not possible.
>> 
>> And once again; I am not arguing against a default implementation that cuts 
>> boilerplate, I am arguing against it being implicit. What I want is to be 
>> the one asking for it, because it is not reasonable to assume that just 
>> throwing it in there is always going to be fine, because it quite simply is 
>> not.
>> _______________________________________________
>> 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