[swift-evolution] [Proposal] Explicit Synthetic Behaviour

Tony Allevato tony.allevato at gmail.com
Tue Sep 12 10:09:00 CDT 2017


On Tue, Sep 12, 2017 at 3:32 AM Vladimir.S <svabox at gmail.com> wrote:

> On 12.09.2017 0:35, Tony Allevato wrote:
> >
> >
> > On Mon, Sep 11, 2017 at 2:05 PM Vladimir.S via swift-evolution
> > <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> >
> >     On 11.09.2017 21:55, Thorsten Seitz via swift-evolution wrote:
> >      > I think I do understand Haravikk's argument (actually it seems
> quite
> >     straightforward
> >      > to me).
> >      >
> >      > An example should be:
> >      >
> >      > struct Foo : Equatable {
> >      >      var x: Int
> >      >      var cachedLabel: String? = nil
> >      >
> >      >      init(x: Int) {
> >      >          self.x = x
> >      >      }
> >      >
> >      >      mutating func label() {
> >      >          if let label = cachedLabel {
> >      >              return label
> >      >          }
> >      >          let label = calculateLabel()
> >      >          cachedLabel = label
> >      >          return cachedLabel
> >      >      }
> >      > }
> >      >
> >      > var foo1 = Foo(x: 1)
> >      > var foo2 = Foo(x: 1)
> >      > foo1 == foo2 // true
> >      > var label = foo1.label()
> >      > foo1 == foo2 // now false, due to cachedString being falsely
> included in the
> >     comparison
> >      >
> >      > The problem is that the developer was not required to implement
> the protocol
> >     and so
> >      > might forget it.
> >      > The difference to other default implementations is that those use
> the protocol
> >     itself
> >      > as building blocks and so are correct with regards to the
> protocol's semantics,
> >      > whereas the synthesized equality reaches deeply into the private
> innards of a
> >     struct
> >      > and therefore is much more likely to be wrong as in the example
> above.
> >      >
> >      > Why not just write
> >      >
> >      > *struct* Foo : *deriving* Equatable {...}
> >      >
> >      > to request the synthesized implementation?
> >
> >     FWIW, +100. The same should be required for Codable. I support the
> opinion that
> >     'synthesized' methods differs from protocol-default-implementation
> in what 'kind' of
> >     data they use: defined by protocol itself or internals of the
> conformed type. And
> >     this can lead to more un-expected problems.
> >
> >     If protocol is able to synthesize its requirements, it should
> require a
> >     'deriving'-like marker when type conforms to it to make it
> absolutely clear what
> >     happens here. It would be not a confusion point, but clarify the
> intention to better
> >     understand the code.
> >
> >     Thinking about *future* custom protocols that could implement
> requirements in default
> >     implementation by using macros/reflection, for me it seems like such
> protocol should
> >     *also* somehow explicitly state that some requirements are
> auto-synthesized, probably
> >     by conforming(derive) to some compiler-magic protocol
> 'AutoSynthesize'.
> >     (i.e. 'protocol MySynthesizeable: AutoSynthesize {...}')
> >
> >     So each built-in protocol like Equatable/Hashable/Codable will
> conform to it, and
> >     also, each custom "auto-synthesizeable" protocol - also should
> explicitly conform to
> >     AutoSynthesize. So, when type conforms to it - such type should use
> 'deriving'-like
> >     marker if auto-generation of methods is expected.
> >
> >
> > This doesn't align with how Swift views the role of protocols, though.
> One of the
> > criteria that the core team has said they look for in a protocol is
> "what generic
> > algorithms would be written using this protocol?" AutoSynthesize doesn't
> satisfy
> > that—there are no generic algorithms that you would write with
> AutoEquatable that
> > differ from what you would write with Equatable.
> >
>
> OK, got it, it was general thoughts, not exact proposal regarding the
> AutoSynthesize
> protocol. Probably it should be @autosynthesize directive for protocol
> when you
> define it or other 'marker', so when you conform to this protocol, you
> *can*
> explicitely use 'derived'-like keyword to make requirements
> auto-synthesized,
> otherwise you'll be asked by compiler for manual implementation.
>
>
> >     I also have a question regarding future direction of 'exclusion' of
> fields from being
> >     included into auto-generated implementation of
> Equatable/Hashable/Codable/other.
> >
> >     If we'll have this 'deriving'-like marker, it seems naturally if we
> mark some member
> >     with some kind of '@noderiving' marker, like here:
> >
> >     struct Foo : deriving Equatable {
> >             var x: Int
> >             var y: Int
> >             var z: Int
> >             @noderiving var cachedLabel: String? = nil
> >     }
> >
> >     this @noderiving directive will work for protocols based on
> AutoSynthesize magic
> >     protocol. I.e., if you construct your own protocol with
> auto-synthesizeable methods,
> >     to be able to *know* which members should be 'excluded' for your
> implementation, you
> >     should base your protocol on AutoSynthesize protocol.
> >
> >
> > This is something I mention in the original proposal, and I agree that
> it would be
> > nice to have added later since there are clear known use cases where
> it's important.
> >
> > However, the feature shouldn't be tied *specifically* to derived
> implementations
> > (meaning it shouldn't be named that way). What we're really talking
> about is
> > "transient" data—data that exists for the purposes of
> caching/performance/etc. but
> > which does not actually contribute to the thing's "value".
> >
> > The fact that transient data should not be ignored for equality,
> hashing, and
> > serialization just happens to align with the protocols that we
> auto-synthesize so
> > far, but it's not necessarily limited to those use cases. If an
> attribute is added
> > for something like this, it should be *semantic* rather than speak to
> implementation
> > details. In other words, it would be inappropriate to say "exclude this
> property from
> > synthesized operations", but it would be fine to say "this property is
> transient
> > data" and it just so happens that Equatable, Hashable, and Codable use
> that
> > information to control what they synthesize.
> >
> > All this is a subtle, but important, distinction. One day, when Swift
> has the ability
> > to introspect metadata about a type and its properties, someone may want
> to use a
> > hypothetical "transient" attribute for something wholly unrelated to
> synthesis.
>
> I see your points, but is it not possible that we want to exclude some
> property for
> Equatable but keep it for Codable, or vise-versa, for example? So,
> actually, IMO we
> need a way to exclude property from some specific protocol/protocols. Like
>
> @transient var ...
> @transient(for:Equatable) var ...
> @transient(for:Codable) var ...
> @transient(for:SomeOtherAuto) var ...
>
> And again, I'm not proposing some concrete syntax/keyword, but think we'll
> need(in
> future,yes, but IMO better to discuss now) a way to 'exclude' specific
> property from
> specific auto-synthesizeable protocol.
>

It's possible, but we shouldn't think of it in terms of "exclude from a
protocol". There are some different combinations to consider here:

* Does it make sense to use a property in a synthesized Hashable but not in
the synthesized Equatable? No, because of the contract between those two
protocols. Such an exclusion would allow two equal values to hash to
different values.

* Does it make sense to use a property in a synthesized Equatable but not
in the synthesized Hashable? Sure; if your data type is large you may only
want to hash a subset of its properties. If that's the case, your hash
function is probably simple enough that you can just override the property
manually, which is more scalable than tagging all the non-hash properties
individually.

* Does it make sense to exclude a property used by synthesized
Equatable/Hashable from synthesized Codable? Sure, maybe. If the property
is truly transient cached data then it can easily be recomputed on demand,
but you could argue that it's worth serializing if doing so is more
efficient than performing the computation again.

The key thing to note here is that "transient" shouldn't mean "exclude from
synthesized implementations". "Transient", at least as I'm describing it,
means "data that does not strictly contribute to something's notion of its
'value'". That's a semantic definition and it's up to the protocols
themselves to decide how to interpret it. If there were a need for
different "levels" of transience, then the attribute could be extended with
more semantic information that lets the protocol decide what to do, or a
new attribute could be introduced. The important thing is that you're
saying "what does this property mean and how does it behave", not "which
specific protocols can or can't do something with this property".

Regarding "what about some future protocol", we can't really consider those
realistically if we don't know what the semantics of that protocol are.



>
> Just my 2 cents why I believe we need an explicit 'derived'-like keyword
> when we want
> auto-synthesized requirement for protocol:
>
> * This will not change the logic/behavior of 'normal' conformance to
> Equatable/Hashable, i.e. if you conform the type to them - you need to
> provide an
> implementation OR (new text in warning message will be added) "use
> 'derived' keyword
> to "auto-synthesize" these methods.
> I.e. auto-synthesize will be something separate, additional, that you can
> use if you
> want it, your clear choose.
> It will not interfere with your 'usual' model of protocol conformance.
>
> * You explicitly mark which protocol you want to be synthesized for you.
> For example,
> if I see "struct S: derived Equatable, Codable" - I understand that
> Equatable will be
> "generated" and Codable will be implemented manually in code.
>
> * This makes code more clean, more understandable by reader, less
> error-prone, more
> explicit on intention. The code *will* be better.
>
> * Without explicit 'derived'-like keyword, the code will be worse : less
> explicit
> about intention, more error-prone, hiding important details from reader,
> etc.
>
> * And the 'derived'-like keyword is good price to have better code in this
> case.
>
> Just my IMOs. Thank you for reading.
>
> Vladimir.
>
> >
> >
> >     I hope this makes any sense :-)
> >
> >     Vladimir.
> >
> >      >
> >      > -Thorsten
> >      >
> >      >
> >      > Am 09.09.2017 um 19:42 schrieb Xiaodi Wu via swift-evolution
> >      > <swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> >     <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org
> >>>:
> >      >
> >      >>
> >      >> On Sat, Sep 9, 2017 at 06:41 Haravikk via swift-evolution
> >      >> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> >     <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>>
> wrote:
> >      >>
> >      >>>     On 9 Sep 2017, at 09:33, Xiaodi Wu <xiaodi.wu at gmail.com
> >     <mailto:xiaodi.wu at gmail.com>
> >      >>>     <mailto:xiaodi.wu at gmail.com <mailto:xiaodi.wu at gmail.com>>>
> wrote:
> >      >>>
> >      >>>
> >      >>>     On Sat, Sep 9, 2017 at 02:47 Haravikk via swift-evolution
> >      >>>     <swift-evolution at swift.org <mailto:
> swift-evolution at swift.org>
> >     <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>>
> wrote:
> >      >>>
> >      >>>
> >      >>>>         On 9 Sep 2017, at 02:02, Xiaodi Wu <
> xiaodi.wu at gmail.com
> >     <mailto:xiaodi.wu at gmail.com>
> >      >>>>         <mailto:xiaodi.wu at gmail.com <mailto:
> xiaodi.wu at gmail.com>>> wrote:
> >      >>>>
> >      >>>>         On Fri, Sep 8, 2017 at 4:00 PM, Itai Ferber via
> >      >>>>         swift-evolution<swift-evolution at swift.org
> >     <mailto:swift-evolution at swift.org>
> >      >>>>         <mailto:swift-evolution at swift.org
> >     <mailto:swift-evolution at swift.org>>>wrote:
> >      >>>>
> >      >>>>
> >      >>>>
> >      >>>>>             On Sep 8, 2017, at 12:46 AM, Haravikk via
> swift-evolution
> >      >>>>>             <swift-evolution at swift.org <mailto:
> swift-evolution at swift.org>
> >     <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>>
> wrote:
> >      >>>>>
> >      >>>>>
> >      >>>>>>             On 7 Sep 2017, at 22:02, Itai Ferber <
> iferber at apple.com
> >     <mailto:iferber at apple.com>
> >      >>>>>>             <mailto:iferber at apple.com <mailto:
> iferber at apple.com>>> 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:
> >      >>>
> >      >>>          1. 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.
> >      >>
> >      >>
> >      >> You are against a default implementation for ==, i.e. an
> implementation that is
> >      >> provided for you if you conform a type to the protocol and do
> nothing else
> >      >> ("implicitly rather than explicitly"), and you are against the
> default
> >      >> implementation being on the existing protocol Equatable
> ("retroactive
> >     change"). So,
> >      >> to summarize, what you are against is precisely a default
> implementation for
> >     the ==
> >      >> requirement on Equatable.
> >      >>
> >      >> This is the topic of discussion here; I am attempting to
> convince you that you
> >      >> should be for rather than against these things.
> >      >>
> >      >>
> >      >>>     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).
> >      >>
> >      >>
> >      >> Right, one must consider the semantics of the specific protocol
> requirement
> >     and ask
> >      >> whether a reasonable default can be provided for it.
> >      >>
> >      >>     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).
> >      >>
> >      >>
> >      >> I am confused why you are trying to argue in general terms about
> the universe of
> >      >> all possible default implementations that use reflection. This
> is necessarily a
> >      >> more difficult argument to make, and if it is to be convincing
> for all default
> >      >> implementations it must also be convincing for the two specific
> protocol
> >      >> requirements we are talking about here. Start small:
> >      >>
> >      >> We have agreed, as a community, that there is a reasonable
> default implementation
> >      >> for Equatable.== when certain conditions are met (for value
> types only at the
> >      >> moment, I believe). Namely, given two values of a type that has
> only Equatable
> >      >> stored properties, those values are equal if their stored
> properties are all
> >     equal.
> >      >> The author of a new value type who wishes to make her type
> Equatable but chooses
> >      >> not to implement a custom == then benefits from this default
> when all stored
> >      >> properties are Equatable.
> >      >>
> >      >>     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.
> >      >>
> >      >>
> >      >> Both options were examined for Codable and for
> Equatable/Hashable. The community
> >      >> and core team decided to prefer the current design. At this
> point, new insights
> >      >> that arise which could not be anticipated at the time of review
> could prompt
> >      >> revision. However, so far, you have presented arguments already
> considered during
> >      >> review.
> >      >>
> >      >>>     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.
> >      >>
> >      >>
> >      >> Again, if it applies generally, it must apply specifically. What
> is
> >     "automatically
> >      >> flawed" about the very reasonable synthesized default
> implementation of ==?
> >      >>
> >      >>>         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.
> >      >>
> >      >>
> >      >> That is not the argument. The argument is that they are
> indistinguishable in the
> >      >> sense that the author of a type who intends to supply a custom
> implementation but
> >      >> neglects to do so will have a default implementation supplied
> for them. It is
> >      >> plainly true that this is no more or less likely to happen
> simply because the
> >      >> default implementation is synthesized.
> >      >>
> >      >>>     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.
> >      >>
> >      >>
> >      >> If you have to ask for it, then it's not a default. You *are*
> against a default
> >      >> implementation.
> >      >>
> >      >>     _______________________________________________
> >      >>     swift-evolution mailing list
> >      >> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> >     <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org
> >>
> >      >> https://lists.swift.org/mailman/listinfo/swift-evolution
> >      >>
> >      >> _______________________________________________
> >      >> swift-evolution mailing list
> >      >> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> >     <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org
> >>
> >      >> https://lists.swift.org/mailman/listinfo/swift-evolution
> >      >
> >      >
> >      > _______________________________________________
> >      > swift-evolution mailing list
> >      > swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> >      > https://lists.swift.org/mailman/listinfo/swift-evolution
> >      >
> >     _______________________________________________
> >     swift-evolution mailing list
> >     swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> >     https://lists.swift.org/mailman/listinfo/swift-evolution
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170912/14a7a809/attachment.html>


More information about the swift-evolution mailing list