<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Wed, Sep 13, 2017 at 11:47 AM Vladimir.S &lt;<a href="mailto:svabox@gmail.com">svabox@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 13.09.2017 20:48, Tony Allevato wrote:<br>
&gt; On Wed, Sep 13, 2017 at 10:21 AM Vladimir.S via swift-evolution<br>
&gt; &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;&gt; wrote:<br>
&gt;<br>
&gt;     On 13.09.2017 19:08, Ondrej Barina via swift-evolution wrote:<br>
&gt;      &gt; Maybe something like this as middle ground.<br>
&gt;      &gt;<br>
&gt;      &gt; protocol Equatable {<br>
&gt;      &gt;      @syntetic static func ==(_ lhs: Self, _ rhs: Self) -&gt; Bool<br>
&gt;      &gt; }<br>
&gt;      &gt;<br>
&gt;      &gt; protocol itself contains default implementation, but without real body.<br>
&gt;     Instead the<br>
&gt;      &gt; function is marked that the real body is generated by compiler.<br>
&gt;      &gt; There is explicit mentions of default impl (by compiler magic), but it does not<br>
&gt;      &gt; affects users as they would still use protocol in normal way:<br>
&gt;      &gt;<br>
&gt;      &gt; struct Foo: Equatable { .... }<br>
&gt;<br>
&gt;     Yes, I also thought about this. And personally for me it is also good solution, while<br>
&gt;     `struct S: Equatable {/*nothing*/}` will *still* lead to compiler&#39;s error or at least<br>
&gt;     warning about not implemented requirements.<br>
&gt;     So, I&#39;ll be explicit regarding my intention: do I want requirements to be<br>
&gt;     auto-generated or I want to do this manually.<br>
&gt;<br>
&gt;     But still. If you see<br>
&gt;<br>
&gt;     struct S: Equatable, Codable {<br>
&gt;         // a lot of lines<br>
&gt;     }<br>
&gt;<br>
&gt;     you can&#39;t say right now if requirements for Equatable and/or Codable was implemented<br>
&gt;     manually or will be auto-generated without checking all the code of a type. This<br>
&gt;     knowledge can help to faster solve issues related to comparison/archiving.<br>
&gt;     So for me the best solution is still &#39;deriving&#39;-like keyword, which adds clarity and<br>
&gt;     show intention without any boilerplate code:<br>
&gt;<br>
&gt;<br>
&gt; The sentences above apply equally to non-synthesized default protocol implementations:<br>
&gt;<br>
&gt; struct S: Foo {<br>
&gt;    // a lot of lines<br>
&gt; }<br>
&gt;<br>
&gt; I can&#39;t say if the requirements for Foo were implemented manually by S or by a<br>
&gt; default implementation in Foo (which could be in a different module that I don&#39;t have<br>
&gt; source access to) without checking all the code for S. So this can&#39;t be used as a<br>
&gt; basis to rationalize special-casing synthesized implementations.<br>
<br>
As was noted in this thread, some people believe that protocol synthesizing its<br>
requirements by accessing type&#39;s fields is of a different kind than &#39;usual&#39; protocol<br>
with default implementation.<br>
I belong to that camp. So, from my point of view, it is important to have<br>
&#39;deriving&#39;-like marker for &#39;auto-senthesizeable&#39; protocols as described above.<br></blockquote><div><br></div><div>Yes, I understand that&#39;s your (and others&#39;) argument. But that argument didn&#39;t apply to the example you gave, which was &quot;I don&#39;t know if S implements a requirement without looking at all of its code.&quot;  You can&#39;t draw the line from that to &quot;therefore S must say it explicitly derives it&quot; as a special case for Equatable because the same premise also applies to non-synthesized default methods.</div><div><br></div><div>Unfortunately I think this thread has reached a bit of a stalemate, so I&#39;m not sure what else I can add. I believe that creating an entirely new axis of protocol conformance is a very weak solution to the &quot;risky defaults&quot; problem, because it&#39;s still all-or-nothing; it doesn&#39;t move users any closer to the goal of eliminating boilerplate by leveraging synthesis. The risk space isn&#39;t unknown—it can be fully described today because the number of protocols that support synthesis are few and finite. The risky situations presented so far have been of the form &quot;I have a type where some property shouldn&#39;t be compared, but the compiler does by default anyway&quot;, then it&#39;s *very* hard for me to support solutions that say &quot;just disable synthesis, but you still have to implement ==/hashValue/etc. by hand&quot; when I can envision solutions that instead say &quot;just tag the single property with appropriate semantics and the compiler can now do what I wanted it to.&quot;</div><div><br></div><div>Make the compiler work for you—don&#39;t make you work for the compiler.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Also, some &#39;usual&#39; protocol Foo can have no default implementations at the moment of<br>
*writing* the code, but can have them at the moment of *compilation* via protocol<br>
extension in separate file in project. So it is not possible to require similar<br>
marker for such protocol.<br>
But Equatable/Hashable/Codable protocols has auto-generation feature already at the<br>
moment of writing the code and we can request that marker.<br>
<br>
Vladimir.<br>
<br>
&gt;<br>
&gt;<br>
&gt;     struct S: Equatable, deriving Codable {<br>
&gt;         // all clear:<br>
&gt;         // manually implemented Equatable<br>
&gt;         // auto-generated Codable<br>
&gt;<br>
&gt;         // a lot of lines<br>
&gt;     }<br>
&gt;<br>
&gt;     Vladimir.<br>
&gt;<br>
&gt;      &gt;<br>
&gt;      &gt; Ondrej B.<br>
&gt;      &gt;<br>
&gt;      &gt; On Wed, Sep 13, 2017 at 4:14 PM, Haravikk via swift-evolution<br>
&gt;      &gt; &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;<br>
&gt;     &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;&gt;&gt; wrote:<br>
&gt;      &gt;<br>
&gt;      &gt;<br>
&gt;      &gt;&gt;     On 13 Sep 2017, at 03:26, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a><br>
&gt;     &lt;mailto:<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt;<br>
&gt;      &gt;&gt;     &lt;mailto:<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a> &lt;mailto:<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt;&gt;&gt; wrote:<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;     On Tue, Sep 12, 2017 at 11:43 AM, Haravikk via<br>
&gt;      &gt;&gt;     swift-evolution&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
&gt;     &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
&gt;     &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;&gt;&gt;wrote:<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;&gt;         On 12 Sep 2017, at 12:08, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a><br>
&gt;     &lt;mailto:<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt;<br>
&gt;      &gt;&gt;&gt;         &lt;mailto:<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a> &lt;mailto:<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt;&gt;&gt; wrote:<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;         On Mon, Sep 11, 2017 at 06:03 Haravikk via swift-evolution<br>
&gt;      &gt;&gt;&gt;&gt;         &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;<br>
&gt;     &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;&gt;&gt; wrote:<br>
&gt;      &gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;             See, this is another flawed assumption; you are assuming that<br>
&gt;      &gt;&gt;&gt;&gt;             omitting a custom implementation of == is always intentional rather<br>
&gt;      &gt;&gt;&gt;&gt;             than an oversight, which is not guaranteed. This is one of my<br>
&gt;     gripes<br>
&gt;      &gt;&gt;&gt;&gt;             with the retroactive change to Equatable, as it is<br>
&gt;      &gt;&gt;&gt;&gt;             currently*impossible* to omit an implementation.<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;         Again, this applies equally to the addition of _any_ default<br>
&gt;      &gt;&gt;&gt;         implementation. And again, such changes don’t even require Swift<br>
&gt;     Evolution<br>
&gt;      &gt;&gt;&gt;         approval.<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;         So what? Because the Swift Evolution process is currently deficient we<br>
&gt;      &gt;&gt;         should just give up on discussing problems with features and the language<br>
&gt;      &gt;&gt;         altogether?<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;     I don&#39;t claim that it&#39;s a deficiency; I claim it&#39;s reflective of Swift&#39;s<br>
&gt;      &gt;&gt;     opinionated take on default implementations. Are you, after all, saying that<br>
&gt;      &gt;&gt;     you have a problem with the addition of _any_ default implementation to an<br>
&gt;      &gt;&gt;     existing protocol? If so, this conversation isn&#39;t about<br>
&gt;     synthesis/reflection at<br>
&gt;      &gt;&gt;     all.<br>
&gt;      &gt;<br>
&gt;      &gt;     No, and you should know that by now. I suggest actually reading some of what I<br>
&gt;      &gt;     have written as I am sick of repeating myself.<br>
&gt;      &gt;<br>
&gt;      &gt;&gt;&gt;&gt;&gt;&gt;             And precisely what kind of &quot;evidence&quot; am I expected to give? This<br>
&gt;      &gt;&gt;&gt;&gt;&gt;&gt;             is a set of features that*do not exist yet*, I am trying to argue<br>
&gt;      &gt;&gt;&gt;&gt;&gt;&gt;             in favour of an explicit end-developer centric opt-in rather than<br>
&gt;      &gt;&gt;&gt;&gt;&gt;&gt;             an implicit protocol designer centric one. Yet no-one seems<br>
&gt;      &gt;&gt;&gt;&gt;&gt;&gt;             interested in the merits of allowing developers to choose<br>
&gt;     what they<br>
&gt;      &gt;&gt;&gt;&gt;&gt;&gt;             want, rather than having implicit behaviours appear potentially<br>
&gt;      &gt;&gt;&gt;&gt;&gt;&gt;             unexpectedly.<br>
&gt;      &gt;&gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;&gt;             Both options were examined for Codable and for Equatable/Hashable.<br>
&gt;      &gt;&gt;&gt;&gt;&gt;             The community and core team decided to prefer the current<br>
&gt;     design. At<br>
&gt;      &gt;&gt;&gt;&gt;&gt;             this point, new insights that arise which could not be anticipated<br>
&gt;      &gt;&gt;&gt;&gt;&gt;             at the time of review could prompt revision. However, so far, you<br>
&gt;      &gt;&gt;&gt;&gt;&gt;             have presented arguments already considered during review.<br>
&gt;      &gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;             And so far all I have heard about this is how it was &quot;decided&quot;;<br>
&gt;      &gt;&gt;&gt;&gt;             no-one seems interested in showing how any of these concerns were<br>
&gt;      &gt;&gt;&gt;&gt;             addressed (if at all), so as far as I can tell they were not,<br>
&gt;     or they<br>
&gt;      &gt;&gt;&gt;&gt;             were wilfully ignored.<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;         They were addressed by being considered.<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;         And yet no-one can apparently summarise what those &quot;considerations&quot; might<br>
&gt;      &gt;&gt;         be, suggesting that they were either *not* considered at all, or that the<br>
&gt;      &gt;&gt;         &quot;consideration&quot; was so weak that no-one is willing to step forward to<br>
&gt;      &gt;&gt;         defend it. Either way it is not sufficient by any reasonable measure.<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;         If I were to run over your foot in my car, would you be happy to accept<br>
&gt;      &gt;&gt;         that I &quot;considered&quot; it first?<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;     How do you mean? People wrote in with their opinions. Then, taking into<br>
&gt;     account<br>
&gt;      &gt;&gt;     the community&#39;s response, the proposal was approved.<br>
&gt;      &gt;<br>
&gt;      &gt;     I mean because not once have you summarised what these alleged<br>
&gt;     &quot;considerations&quot;<br>
&gt;      &gt;     were; if they exist then you should be able do so, yet all I am hearing is &quot;it<br>
&gt;      &gt;     was considered&quot;, which frankly is not an argument at all as it is entirely<br>
&gt;      &gt;     without substance.<br>
&gt;      &gt;<br>
&gt;      &gt;     If it was genuinely considered then someone should be able to say what points<br>
&gt;      &gt;     were considered and what conclusions were reached and why. And even if there<br>
&gt;      &gt;     *was* an earlier decision, that doesn&#39;t necessarily make it right. We are<br>
&gt;      &gt;     discussing it now, and it is clear that any decision that has been made<br>
&gt;     has been<br>
&gt;      &gt;     made poorly at best.<br>
&gt;      &gt;<br>
&gt;      &gt;     And if you&#39;re talking about the discussion on Equatable/Hashable specifically,<br>
&gt;      &gt;     I&#39;m afraid your memory of the &quot;considerations&quot; is radically different to<br>
&gt;     mine; as<br>
&gt;      &gt;     the concerns I raised were essentially ignored, as not a single person gave a<br>
&gt;      &gt;     justification more substantial than &quot;but, but Codable!&quot; which frankly isn&#39;t a<br>
&gt;      &gt;     justification at all.<br>
&gt;      &gt;<br>
&gt;      &gt;&gt;&gt;&gt;&gt;&gt;                 Therefore, your argument reduces to one about which default<br>
&gt;      &gt;&gt;&gt;&gt;&gt;&gt;                 implementations generally ought or ought not to be<br>
&gt;      &gt;&gt;&gt;&gt;&gt;&gt;                 provided--that is, that they ought to be provided only when<br>
&gt;      &gt;&gt;&gt;&gt;&gt;&gt;                 their correctness can be guaranteed for all (rather than<br>
&gt;     almost<br>
&gt;      &gt;&gt;&gt;&gt;&gt;&gt;                 all) possible conforming types. To which point I sketched a<br>
&gt;      &gt;&gt;&gt;&gt;&gt;&gt;                 rebuttal above.<br>
&gt;      &gt;&gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 If a protocol defines something, and creates a default<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 implementation based only upon those definitions then it<br>
&gt;     must by<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 its very nature be correct. A concrete type may later<br>
&gt;     decided to<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 go further, but that is a feature of the concrete type, not a<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 failure of the protocol itself which can function correctly<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 within the context it created. You want to talk evidence, yet<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 there has been no example given that proves otherwise;<br>
&gt;     thus far<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 only Itai has attempted to do so, but I have already<br>
&gt;     pointed out<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 the flaws with that example.<br>
&gt;      &gt;&gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 The simple fact is that a default implementation may either be<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 flawed or not within the context of the protocol itself; but a<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 reflective or synthetic implementation by its very nature goes<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 beyond what the protocol defines and so is automatically<br>
&gt;     flawed<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 because as it does not rely on the end-developer to confirm<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 correctness, not when provided implicitly at least.<br>
&gt;      &gt;&gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;&gt;             Again, if it applies generally, it must apply specifically.<br>
&gt;     What is<br>
&gt;      &gt;&gt;&gt;&gt;&gt;             &quot;automatically flawed&quot; about the very reasonable synthesized<br>
&gt;     default<br>
&gt;      &gt;&gt;&gt;&gt;&gt;             implementation of ==?<br>
&gt;      &gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;             It makes the assumption that every equatable property of a type is<br>
&gt;      &gt;&gt;&gt;&gt;             necessarily relevant to its equality.<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;         No necessarily, only provisionally and rebuttably. If it’s not the case,<br>
&gt;      &gt;&gt;&gt;         override the default.<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;         So… entirely unlike standard default implementations<br>
&gt;      &gt;&gt;         which*cannot* &quot;provisionally&quot; assume something is relevant at all,<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;     Why not?<br>
&gt;      &gt;<br>
&gt;      &gt;     Because they can only act upon properties/methods that they themselves (or a<br>
&gt;      &gt;     parent protocol) define. FFS, what is so unclear about that? Or are you<br>
&gt;     arguing<br>
&gt;      &gt;     on this subject without every having actually used a protocol before?<br>
&gt;      &gt;<br>
&gt;      &gt;&gt;         thereby making them entirely different from synthesised/reflective<br>
&gt;      &gt;&gt;         implementations!<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;         I&#39;m sorry, but you keep trying to argue that they&#39;re the same, but then<br>
&gt;      &gt;&gt;         admitting that they&#39;re not. You can&#39;t have it both ways.<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;     Well, certainly, synthesized default implementations differ from<br>
&gt;      &gt;&gt;     non-synthesized ones in key respects. However, they do not differ in terms of<br>
&gt;      &gt;&gt;     the user experience of conforming to the protocol and having to override the<br>
&gt;      &gt;&gt;     default.<br>
&gt;      &gt;<br>
&gt;      &gt;     Except that that&#39;s not true at all, is it?<br>
&gt;      &gt;<br>
&gt;      &gt;     Synthesised default implementations go much further in how they attempt (and<br>
&gt;      &gt;     potentially fail) to implement those defaults, and in the specific case of<br>
&gt;      &gt;     Equatable/Hashable they are fully implementing a protocol without a single<br>
&gt;      &gt;     property of method being raised as a requirement; they are utterly<br>
&gt;     different at a<br>
&gt;      &gt;     fundamental level, no amount of mental contortion changes that fact.<br>
&gt;      &gt;<br>
&gt;      &gt;&gt;&gt;&gt;             Consider for example if a type stores a collection index for<br>
&gt;      &gt;&gt;&gt;&gt;             performance reasons; this isn&#39;t an intrinsic part of the type, nor<br>
&gt;      &gt;&gt;&gt;&gt;             relevant to testing equality, yet this default implementation will<br>
&gt;      &gt;&gt;&gt;&gt;             treat it as such because it*knows nothing about the concrete type&#39;s<br>
&gt;      &gt;&gt;&gt;&gt;             properties*. If a protocol does not define a property then any<br>
&gt;     action<br>
&gt;      &gt;&gt;&gt;&gt;             taken upon such a property is necessarily based upon an assumption;<br>
&gt;      &gt;&gt;&gt;&gt;             just because it might be fine some of the time, does not make<br>
&gt;     it any<br>
&gt;      &gt;&gt;&gt;&gt;             less flawed.<br>
&gt;      &gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;             The big difference here between explicit and implicit synthetic<br>
&gt;      &gt;&gt;&gt;&gt;             implementations is where this assumption originates; if a method is<br>
&gt;      &gt;&gt;&gt;&gt;             synthesised implicitly then the assumption is made by the protocol<br>
&gt;      &gt;&gt;&gt;&gt;             designer alone, with no real involvement by the end developer. If I<br>
&gt;      &gt;&gt;&gt;&gt;             explicitly opt-in to that default however I am signalling to the<br>
&gt;      &gt;&gt;&gt;&gt;             protocol that it is okay to proceed. In the former case the<br>
&gt;      &gt;&gt;&gt;&gt;             assumption is unreasonable, in the latter it is explicitly<br>
&gt;      &gt;&gt;&gt;&gt;             authorised. It is a difference between &quot;I want to make the decision<br>
&gt;      &gt;&gt;&gt;&gt;             on what&#39;s correct&quot; and &quot;I am happy for you (the protocol<br>
&gt;     designer) to<br>
&gt;      &gt;&gt;&gt;&gt;             decide&quot;.<br>
&gt;      &gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;             Right now, when I conform to Equatable, it is a declaration of &quot;I<br>
&gt;      &gt;&gt;&gt;&gt;             will implement this&quot;, but with this retroactive implicit change<br>
&gt;     it is<br>
&gt;      &gt;&gt;&gt;&gt;             now a declaration of &quot;implement this for me&quot;, these are two<br>
&gt;     entirely<br>
&gt;      &gt;&gt;&gt;&gt;             different things. Consider; what if I&#39;m working on a piece of code<br>
&gt;      &gt;&gt;&gt;&gt;             that requires types to be Equatable, but one of the types I&#39;m using<br>
&gt;      &gt;&gt;&gt;&gt;             currently isn&#39;t, so I quickly throw Equatable conformance onto<br>
&gt;     it and<br>
&gt;      &gt;&gt;&gt;&gt;             go back to what I was doing, with the intention of completing<br>
&gt;      &gt;&gt;&gt;&gt;             conformance later. With this change that type may now receive a<br>
&gt;      &gt;&gt;&gt;&gt;             default implementation that is wrong, and I&#39;ve lost the safety net<br>
&gt;      &gt;&gt;&gt;&gt;             that currently exists.<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;         Right now, it still wouldn’t compile, so I don’t see why you would do<br>
&gt;      &gt;&gt;&gt;         that. In the future, if you want to make it not compile, there is<br>
&gt;     nothing<br>
&gt;      &gt;&gt;&gt;         stopping you from conforming to a non-existent “NotYetEquatable”.<br>
&gt;     This was<br>
&gt;      &gt;&gt;&gt;         something that you asked about earlier and it was answered.<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;         So your solution is to intentionally write invalid code to work<br>
&gt;     around the<br>
&gt;      &gt;&gt;         fact that a feature is being implemented badly?<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;     You stated a use case where you *want* the compiler to stop your code from<br>
&gt;      &gt;&gt;     compiling by stating a conformance to Equatable without implementing its<br>
&gt;      &gt;&gt;     requirements. You then stated that the major problem you have with<br>
&gt;     synthesized<br>
&gt;      &gt;&gt;     `==` is that the compiler will now use a default implementation that you<br>
&gt;     might<br>
&gt;      &gt;&gt;     forget about instead of stopping compilation. Therefore, I demonstrated<br>
&gt;     how you<br>
&gt;      &gt;&gt;     could continue to have the compiler stop your code from compiling. It&#39;s<br>
&gt;     not my<br>
&gt;      &gt;&gt;     solution that is intentionally writing invalid code; your stated aim was<br>
&gt;     to be<br>
&gt;      &gt;&gt;     able to do so.<br>
&gt;      &gt;<br>
&gt;      &gt;     My stated aim was nothing of the sort.<br>
&gt;      &gt;<br>
&gt;      &gt;     I was pointing out that right now conforming to Equatable means something<br>
&gt;      &gt;     entirely different from what it will mean in future if this idiotic change<br>
&gt;     makes<br>
&gt;      &gt;     it into release. Please actually read what I write before deciding for<br>
&gt;     yourself<br>
&gt;      &gt;     what my &#39;stated aim&#39; is.<br>
&gt;      &gt;<br>
&gt;      &gt;     I am *not* asking for workarounds to circumvent a ridiculously flawed<br>
&gt;     change to<br>
&gt;      &gt;     the language, I am arguing why it is flawed and must be changed. If I wanted a<br>
&gt;      &gt;     workaround I&#39;d do what I&#39;m now seriously considering, which is ditching Swift<br>
&gt;      &gt;     completely, as I will not use a language if I can no longer trust the team<br>
&gt;      &gt;     developing it or the decisions that they make.<br>
&gt;      &gt;<br>
&gt;      &gt;&gt;&gt;&gt;             A non-synthesised/reflective implementation cannot strictly be<br>
&gt;      &gt;&gt;&gt;&gt;             incorrect, because as long as it is implemented properly it will<br>
&gt;      &gt;&gt;&gt;&gt;             always be correct within the context of the protocol itself. It may<br>
&gt;      &gt;&gt;&gt;&gt;             not go quite as far as an end developer might want, but that is<br>
&gt;      &gt;&gt;&gt;&gt;             because they want to add something onto the protocol, not<br>
&gt;     because the<br>
&gt;      &gt;&gt;&gt;&gt;             protocol is wrong.<br>
&gt;      &gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;             A synthesised/reflective implementation differs because if it goes<br>
&gt;      &gt;&gt;&gt;&gt;             too far it is wrong not only within the context of the concrete<br>
&gt;     type,<br>
&gt;      &gt;&gt;&gt;&gt;             but also the protocol itself, it is simply incorrect.<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;         Again, this is an assertion that misses the mark. If the default<br>
&gt;      &gt;&gt;&gt;         implementation is unsuitable for a type, it’s unsuitable whether it<br>
&gt;      &gt;&gt;&gt;         “doesn’t go quite as far” or “goes too far.”<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;         Because not going quite far enough is not a failure of the protocol, as<br>
&gt;      &gt;&gt;         protocols by their very nature can only go as far as what they<br>
&gt;     define. If a<br>
&gt;      &gt;&gt;         protocol Foo defines two properties, a method which uses those two<br>
&gt;      &gt;&gt;         properties correctly, then the method is correct. A developer of a<br>
&gt;     concrete<br>
&gt;      &gt;&gt;         type might want to add more information or tailor the behaviour, but that<br>
&gt;      &gt;&gt;         doesn&#39;t make the default implementation incorrect, it&#39;s just considering<br>
&gt;      &gt;&gt;         the type only within the context of being an instance of Foo.<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;         Going too far is the opposite; it&#39;s the protocol designer messing around<br>
&gt;      &gt;&gt;         with stuff they do not define at all. It&#39;s only ever right by chance, as<br>
&gt;      &gt;&gt;         it&#39;s operating within the context of the concrete type, about which the<br>
&gt;      &gt;&gt;         protocol does not know anything with certainty.<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;     Yes, you have defined &quot;not going far enough&quot; and &quot;going too far&quot; based on<br>
&gt;      &gt;&gt;     whether an implementation uses only protocol requirements or not.<br>
&gt;     However, you<br>
&gt;      &gt;&gt;     haven&#39;t at all demonstrated why this distinction is at all meaningful in<br>
&gt;     terms<br>
&gt;      &gt;&gt;     of the issue you describe with a user conforming to a protocol. If there is a<br>
&gt;      &gt;&gt;     default implementation, either it returns the expected result for the<br>
&gt;      &gt;&gt;     conforming type or it does not--those are the only two choices. Are you<br>
&gt;     arguing<br>
&gt;      &gt;&gt;     that, empirically, the default implementation for Equatable will more<br>
&gt;     often be<br>
&gt;      &gt;&gt;     unsuitable for conforming types? If so, what&#39;s your evidence?<br>
&gt;      &gt;<br>
&gt;      &gt;     What&#39;s yours? If this issue was as &quot;considered&quot; as you constantly claim then<br>
&gt;      &gt;     where is the evidence that there is no meaningful distinction? Surely such<br>
&gt;      &gt;     evidence exists, or else the issue hasn&#39;t been considered at all, has it?<br>
&gt;      &gt;<br>
&gt;      &gt;     Frankly I am sick of being asked to provide evidence when you are seemingly<br>
&gt;      &gt;     unwilling to do anything in return, especially when you have conveniently<br>
&gt;     ignored<br>
&gt;      &gt;     every single example that I have already given.<br>
&gt;      &gt;<br>
&gt;      &gt;     It cuts both ways; you claim that &quot;going too far&quot; and &quot;not going far<br>
&gt;     enough&quot; are<br>
&gt;      &gt;     the same thing? Well prove it.<br>
&gt;      &gt;<br>
&gt;      &gt;&gt;&gt;         You state but do not give any rationale for the claim that the former is<br>
&gt;      &gt;&gt;&gt;         not wrong in some context while the latter is always wrong.<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;         By this line of argumentation, you’d be perfectly content if instead we<br>
&gt;      &gt;&gt;&gt;         simply had the default implementation of == as “return true” because it<br>
&gt;      &gt;&gt;&gt;         would be somehow not wrong.<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;         Only if return true were a reasonable default to give in the context<br>
&gt;     of the<br>
&gt;      &gt;&gt;         protocol, which it clearly is not, as it&#39;s not performing any kind of<br>
&gt;      &gt;&gt;         comparison of equality.<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;     Sure it is; `return true` satisfies all the semantic requirements for<br>
&gt;     equality:<br>
&gt;      &gt;&gt;     reflexivity, symmetry, transitivity; and, in the context of the protocol<br>
&gt;     which<br>
&gt;      &gt;&gt;     only provides for this one facility (determination of equality or<br>
&gt;     inequality),<br>
&gt;      &gt;&gt;     any two instances that compare equal _are_ completely interchangeable &quot;within<br>
&gt;      &gt;&gt;     the context of the protocol itself,&quot; as you would say.<br>
&gt;      &gt;<br>
&gt;      &gt;     The purpose of Equatable is to identify types that can be compared for<br>
&gt;     equality;<br>
&gt;      &gt;     returning true does not satisfy that aim because no such comparison is<br>
&gt;     occurring,<br>
&gt;      &gt;     so your example is intentionally ridiculous. Even a less contrived example<br>
&gt;     such<br>
&gt;      &gt;     as comparing memory addresses doesn&#39;t fulfil the purpose of Equatable,<br>
&gt;     which is<br>
&gt;      &gt;     all about comparing equality of different instances that might still be<br>
&gt;     the same.<br>
&gt;      &gt;<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 Put another way, what the proposal about synthesizing<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 implementations for Equatable and Hashable was about can be<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 thought of in two parts: (a) should there be default<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 implementations; and (b) given that it is impossible to write<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 these in Swift, should we use magic? Now, as I said above,<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 adding default implementations isn&#39;t (afaik) even<br>
&gt;     considered an<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 API change that requires review on this list. Really, what<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 people were debating was (b), whether it is worth it to<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 implement compiler-supported magic to make these possible.<br>
&gt;     Your<br>
&gt;      &gt;&gt;&gt;&gt;&gt;                 disagreement has to do with (a) and not (b).<br>
&gt;      &gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;                 Wrong. The use of magic in this case produces something else<br>
&gt;      &gt;&gt;&gt;&gt;                 entirely; that&#39;s the whole point. It is*not the same*,<br>
&gt;     otherwise<br>
&gt;      &gt;&gt;&gt;&gt;                 it wouldn&#39;t be needed at all. It doesn&#39;t matter if it&#39;s<br>
&gt;     compiler<br>
&gt;      &gt;&gt;&gt;&gt;                 magic, some external script or a native macro, ultimately they<br>
&gt;      &gt;&gt;&gt;&gt;                 are all doing something with a concrete type that is currently<br>
&gt;      &gt;&gt;&gt;&gt;                 not possible.<br>
&gt;      &gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;                 And once again;*I am not arguing against a default<br>
&gt;     implementation<br>
&gt;      &gt;&gt;&gt;&gt;                 that cuts boilerplate*, I am arguing against it being implicit.<br>
&gt;      &gt;&gt;&gt;&gt;                 What I want is to be the one asking for it, because it is not<br>
&gt;      &gt;&gt;&gt;&gt;                 reasonable to assume that just throwing it in there is always<br>
&gt;      &gt;&gt;&gt;&gt;                 going to be fine, because it quite simply is not.<br>
&gt;      &gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;             If you have to ask for it, then it&#39;s not a default. You *are*<br>
&gt;     against<br>
&gt;      &gt;&gt;&gt;&gt;             a default implementation.<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;             A default implementation is an implementation that I, as the<br>
&gt;     concrete<br>
&gt;      &gt;&gt;&gt;             type developer, do not have to provide myself. If you want<br>
&gt;     default to<br>
&gt;      &gt;&gt;&gt;             mean only &quot;automatic&quot; then your attempt to pigeon-hole what I am<br>
&gt;      &gt;&gt;&gt;             arguing is incorrect, because what I am arguing is then neither<br>
&gt;     about<br>
&gt;      &gt;&gt;&gt;             default implementations nor the means of actually implementing<br>
&gt;     it, but<br>
&gt;      &gt;&gt;&gt;             something else entirely.<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;             But as far as I&#39;m concerned it still absolutely still a default<br>
&gt;      &gt;&gt;&gt;             implementation whether it is requested or not; the difference is<br>
&gt;     I, as<br>
&gt;      &gt;&gt;&gt;             the end developer, am able to refine what type of defaults that<br>
&gt;     I want.<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;         The word “default” indicates something that arises in the absence of a<br>
&gt;      &gt;&gt;&gt;         user indication otherwise.<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;         Then this proposal is just for a different mechanism for &quot;indicating<br>
&gt;      &gt;&gt;         otherwise&quot;.<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;         You keep trying to argue that a synthesised/reflective default<br>
&gt;      &gt;&gt;         implementation is the same as a normal default implementation, yet<br>
&gt;     you seem<br>
&gt;      &gt;&gt;         to be consistently forgetting that even if that is true without this<br>
&gt;      &gt;&gt;         proposal, that the very proposal itself is to change that, effectively<br>
&gt;      &gt;&gt;         causing a category of default implementation to become explicitly<br>
&gt;      &gt;&gt;         opted-into, rather than implicitly. They&#39;re still implementations<br>
&gt;     that will<br>
&gt;      &gt;&gt;         be provided automatically, just only when they are permitted to do-so.<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;     So to be clear, you are *against* them being the *default*: you wish them<br>
&gt;     to be<br>
&gt;      &gt;&gt;     the *otherwise*.<br>
&gt;      &gt;<br>
&gt;      &gt;     You seem to be insisting upon a narrow definition of default; what I want is<br>
&gt;      &gt;     control over which types of default implementations are provided. Just because<br>
&gt;      &gt;     they must be opted-into explicitly does not stop them being &quot;default&quot;, as they<br>
&gt;      &gt;     are still implementations that I myself do not need to implement. The<br>
&gt;     difference<br>
&gt;      &gt;     is that I want to actually *want* them rather than have provided through<br>
&gt;      &gt;     potentially flimsy assumptions made by a protocol designer. Just because<br>
&gt;     there&#39;s<br>
&gt;      &gt;     an extra step doesn&#39;t make them any less automatic, otherwise having to<br>
&gt;     conform<br>
&gt;      &gt;     to a protocol in the first place would also prevent them from being defaults.<br>
&gt;      &gt;<br>
&gt;      &gt;     Asking *for* something is more like a middle-ground between the two; the<br>
&gt;      &gt;     synthetic implementations are still possible defaults, they just aren&#39;t<br>
&gt;     provided<br>
&gt;      &gt;     unless you allow them, while omitting the necessary keyword/attribute prevents<br>
&gt;      &gt;     them being used.<br>
&gt;      &gt;<br>
&gt;      &gt;&gt;&gt;&gt;             On 9 Sep 2017, at 23:17, Gwendal Roué &lt;<a href="mailto:gwendal.roue@gmail.com" target="_blank">gwendal.roue@gmail.com</a><br>
&gt;     &lt;mailto:<a href="mailto:gwendal.roue@gmail.com" target="_blank">gwendal.roue@gmail.com</a>&gt;<br>
&gt;      &gt;&gt;&gt;&gt;             &lt;mailto:<a href="mailto:gwendal.roue@gmail.com" target="_blank">gwendal.roue@gmail.com</a><br>
&gt;     &lt;mailto:<a href="mailto:gwendal.roue@gmail.com" target="_blank">gwendal.roue@gmail.com</a>&gt;&gt;&gt; wrote:<br>
&gt;      &gt;&gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;&gt;             All right, I&#39;ll be more positive: our science, IT, is a<br>
&gt;      &gt;&gt;&gt;&gt;             *constructive* science, by *essence*. If there is a problem, there<br>
&gt;      &gt;&gt;&gt;&gt;             must be a way to show it.<br>
&gt;      &gt;&gt;&gt;&gt;             It you can&#39;t, then there is no problem.<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;             You mean just as I have asked for examples that prove<br>
&gt;      &gt;&gt;&gt;             non-synthetic/reflective default implementations are as dangerous as<br>
&gt;      &gt;&gt;&gt;             synthetic/reflective ones? Plenty have suggested this is the<br>
&gt;     case yet<br>
&gt;      &gt;&gt;&gt;             no reasonable examples of that have been given either.<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;             However, examples highlighting problems with the synthesised<br>
&gt;     behaviour<br>
&gt;      &gt;&gt;&gt;             are simple:<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;                 structFoo :Equatable{vardata:String}// Currently an error, won&#39;t<br>
&gt;      &gt;&gt;&gt;                 be in future<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;             Or something a bit more substantial:<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;                 structKeyPair :Equatable{<br>
&gt;      &gt;&gt;&gt;                 staticvarcount:Int=0<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;                 varcount:Int<br>
&gt;      &gt;&gt;&gt;                 letkey:String// This is the only property that should be<br>
&gt;     equatable<br>
&gt;      &gt;&gt;&gt;                 varvalue:String<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;                 init(key:String, value:String) {<br>
&gt;      &gt;&gt;&gt;                 letcount =KeyPair.count&amp;+1<br>
&gt;      &gt;&gt;&gt;                 KeyPair.count= count;self.count= count<br>
&gt;      &gt;&gt;&gt;                 self.key= key;self.value= value<br>
&gt;      &gt;&gt;&gt;                 }<br>
&gt;      &gt;&gt;&gt;                 }<br>
&gt;      &gt;&gt;&gt;<br>
&gt;      &gt;&gt;&gt;             Here the only important property in the key pair is the key, the<br>
&gt;     value<br>
&gt;      &gt;&gt;&gt;             isn&#39;t important (only the keys are to be considered unique) and the<br>
&gt;      &gt;&gt;&gt;             count is just a throwaway value. The synthesised default<br>
&gt;      &gt;&gt;&gt;             implementation for this concrete type will therefore be completely<br>
&gt;      &gt;&gt;&gt;             wrong, likewise for Hashable, which will likely produce radically<br>
&gt;      &gt;&gt;&gt;             different results for instances that should be the same.<br>
&gt;      &gt;&gt;<br>
&gt;      &gt;&gt;         I notice that despite asking endlessly for examples, the ones I&#39;ve given<br>
&gt;      &gt;&gt;         are being ignored. In future I shall remind people asking for examples<br>
&gt;      &gt;&gt;         where they can shove them.<br>
&gt;      &gt;<br>
&gt;      &gt;     And once again, totally ignored. You seem to love asking for &quot;evidence&quot;<br>
&gt;     but why<br>
&gt;      &gt;     exactly should I bother giving anything if you ignore it when I try to?<br>
&gt;      &gt;<br>
&gt;      &gt;     _______________________________________________<br>
&gt;      &gt;     swift-evolution mailing list<br>
&gt;      &gt; <a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;<br>
&gt;     &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;&gt;<br>
&gt;      &gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
&gt;      &gt;     &lt;<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a>&gt;<br>
&gt;      &gt;<br>
&gt;      &gt;<br>
&gt;      &gt;<br>
&gt;      &gt;<br>
&gt;      &gt; _______________________________________________<br>
&gt;      &gt; swift-evolution mailing list<br>
&gt;      &gt; <a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;<br>
&gt;      &gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
&gt;      &gt;<br>
&gt;     _______________________________________________<br>
&gt;     swift-evolution mailing list<br>
&gt;     <a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;<br>
&gt;     <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
&gt;<br>
</blockquote></div></div>