[swift-evolution] [Proposal] Explicit Synthetic Behaviour

Vladimir.S svabox at gmail.com
Tue Sep 12 05:32:13 CDT 2017


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.


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
> 


More information about the swift-evolution mailing list