Some thoughts on updated proposal: • I strongly believe factory initializers should follow the progressive disclosure pattern, and importing all Objective-C initializers as factory initializers breaks this. While there is precedent for this because of the "open" access control, I'd prefer if maybe we compromised and any @objc initializer is assumed to have the same performance characteristics as a factory initializer, without having to prepend the factory keyword. • While I did initially propose the factory keyword, I'm still not entirely sure "factory" is the right choice. Though if the consensus that is the right keyword, then I'll happily accept that. • Having "self" refer to the dynamic type of the returned instance seems...weird. While technically correct for a static method, I'd expect self to be an instance and Self to be the dynamic type just like any other initializer. • Factory initializers should be used for any initializer that returns a value. Furthermore, I don't think we should limit factory initializers to just protocol extensions and classes. Sure it doesn't make sense for value types, but I don't think we should forbid that (and that way if you want to return a value instead of a assign to self, you'd just use factory intializer) • I don't think there should be any delegating to other factory initializers. Nothing would stop you from returning a value initialized via another factory method, however.
Sorry if sounds a little rambled, don't have access to a computer for the rest of the day so typing this all up on my phone! > On Jun 11, 2017, at 1:39 PM, Gor Gyolchanyan via swift-evolution > <swift-evolution@swift.org> wrote: > > Here's the updated proposal: > > https://github.com/technogen-gg/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md > > Is there anything else or are we good to go? > >> On Jun 11, 2017, at 8:46 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote: >> >>> On Sun, Jun 11, 2017 at 12:43 PM, Gor Gyolchanyan <g...@gyolchanyan.com> >>> wrote: >>> I have no better name besides a factory initializer for now. >>> I have thought about this some more and came to this conclusion about the >>> keyword: >>> Let the keyword be universally applied to all factory initializers, to >>> statically enforce the rules of factory initializers (see below), because >>> the more I think of it, the more I realize that you'd generally not want to >>> mix factory and non-factory initializers, due to their vastly differing >>> purposes. >>> >>> Having said that, my current understanding of this proposal is as follows: >>> >>> * Allow marking initializers inside protocol extensions, class declarations >>> and class extensions as `factory`. >>> * In initializers marked as `factory`: >>> * Change the implicit `self` parameter to mean `the dynamic type of the >>> enclosing type` (just like it does in static methods). >>> * Disallow delegating initialization to initializers not marked as >>> `factory`. >>> * Require terminating the initializer by either returning a compatible >>> type (a conforming type for protocols, a derived instance for classes) or >>> returning `nil` (if the initializer is failable). >>> * In initializers inside enum declarations, enum extensions, struct >>> declarations and struct extensions: >>> * Allow terminating the initializer by returning an instance of the >>> type being initialized. >> >> Sounds reasonable to me. >> >>>> On Jun 11, 2017, at 7:38 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote: >>>> >>>>> On Sun, Jun 11, 2017 at 10:34 AM, Gor Gyolchanyan <g...@gyolchanyan.com> >>>>> wrote: >>>>> I just didn't want to use the commonly proposed `factory` word, because >>>>> it implies a specific semantic tied to the factory method pattern. >>>>> I gave it another thought and I'm thinking maybe we can forego the >>>>> annotation and have the compiler deduce it automatically. >>>>> There are only two places where an indirect initializer can exist: >>>>> * Protocol extensions, returning a conforming type. >>>>> * Classes, returning an instance. >>>>> It doesn't make sense to have this on value types, since they do not have >>>>> subtypes of any kind. >>>>> Indirect initializers are very unambiguous in protocol extensions, >>>>> because the only other way of implementing an initializer in a protocol >>>>> extension is via delegating initialization, so the indirect-ness of the >>>>> initializer can be statically determined by whether or not there is a >>>>> delegating initializer involved. >>>>> If the initializer in a protocol extension has a delegating >>>>> initialization on any execution path, then returning an instance is >>>>> disallowed and vice versa. This will ensure strict separation of >>>>> initializer types for the compiler to generate code for. >>>>> If a failable initializer in a protocol extension unconditionally returns >>>>> `nil`, then no initialization takes place anyway, so it doesn't matter, >>>>> which one the compiler chooses. >>>>> In classes this is a bit difficult, because besides delegating >>>>> initializers, they also can initialize the members directly. >>>>> So, in addition to the distinguishing rule for the protocol extensions, >>>>> classes will also check whether any member is assigned to on any >>>>> execution path. >>>>> >>>>> What do you think? >>>> >>>> Keywords aren't just for the compiler; they're for the human reader too! >>>> If you believe the use of your proposed feature in protocol extensions is >>>> unambiguous to humans as well as compilers, then IMO it makes sense not to >>>> require another keyword in that place. I haven't thought deeply about >>>> whether that would be the case. >>>> >>>> Clearly, you're saying that this is a more complicated situation with >>>> classes; I think it makes sense for you to consider requiring a keyword >>>> there. There is precedent for keywords modifying `init` to be required for >>>> classes but not for value types (e.g., `convenience`). >>>> >>>> Regardless of whether a keyword is required or not, your feature needs a >>>> name. And here again, I think it is puzzling that you are calling them >>>> "indirect initializers" when there is already another meaning for >>>> "indirect" in Swift. Distinct concepts should have distinct names. >>>> >>>>>> On Jun 11, 2017, at 5:53 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote: >>>>>> >>>>>>> On Sun, Jun 11, 2017 at 8:49 AM, Gor Gyolchanyan <g...@gyolchanyan.com> >>>>>>> wrote: >>>>>>> Can you recall the reasons why the removal of access modifiers on >>>>>>> extensions was rejected? >>>>>> >>>>>> It was an unassailable reason, really: people found this shorthand >>>>>> useful and wanted to continue to use it--it is the only way to specify >>>>>> that multiple members are public without explicitly labeling each one. >>>>>> The core team agreed it was useful. >>>>>> >>>>>> My takeaway from the whole episode (I was greatly in favor of removing >>>>>> this shorthand, as it's highly inconsistent with all other access >>>>>> modifier rules) is that in general, since the bar for new syntax is so >>>>>> high, if a shorthand made it into the language (and especially if it's >>>>>> kind of an inconsistent shorthand) the general presumption must be that >>>>>> it is highly desired. >>>>>> >>>>>>> Also, do you think `indirect init` is confusing inside an `indirect >>>>>>> enum`? >>>>>> >>>>>> I do. These are unrelated definitions of "indirect," and I'm puzzled why >>>>>> you'd actively choose to run into issues with the same word meaning two >>>>>> things when you could choose another word. >>>>>> >>>>>>>> On Jun 11, 2017, at 4:40 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote: >>>>>>>> >>>>>>>> Removal of access modifiers on extensions has been proposed, reviewed, >>>>>>>> and rejected, so that’s that. >>>>>>>> >>>>>>>> In general, Swift uses distinct keywords for distinct concepts, unlike >>>>>>>> Rust which likes to reuse keywords in clever ways; if you’re finding >>>>>>>> that things are getting confusing with one word meaning two things, >>>>>>>> that shouldn’t be an invitation to rip out existing syntax but is >>>>>>>> probably a good sign you shouldn’t be repurposing that keyword. >>>>>>>> >>>>>>>> >>>>>>>>> On Sun, Jun 11, 2017 at 03:28 Adrian Zubarev via swift-evolution >>>>>>>>> <swift-evolution@swift.org> wrote: >>>>>>>>> Yeah, well I messed up my proposal from last year about removing the >>>>>>>>> access modifier on extensions and wish now I wasn’t that confused >>>>>>>>> back than and made it right. >>>>>>>>> >>>>>>>>> The indirect keyword is literally the same story. The docs only says >>>>>>>>> that this is only a shortcut. >>>>>>>>> >>>>>>>>> „To enable indirection for all the cases of an enumeration, mark the >>>>>>>>> entire enumeration with the indirect modifier—this is convenient when >>>>>>>>> the enumeration contains many cases that would each need to be marked >>>>>>>>> with the indirect modifier.“ >>>>>>>>> >>>>>>>>> If you really wish to reuse that keyword here we might need to remove >>>>>>>>> such shortcuts from the language (indirect enum, access modifier on >>>>>>>>> extensions, anything else?). >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Adrian Zubarev >>>>>>>>> Sent with Airmail >>>>>>>>> >>>>>>>>> Am 11. Juni 2017 um 10:12:38, Gor Gyolchanyan (g...@gyolchanyan.com) >>>>>>>>> schrieb: >>>>>>>>> >>>>>>>>>> I always wondered, why is `indirect` allowed on the `enum` itself? >>>>>>>>>> Wouldn't it make more sense to apply it to individual cases that >>>>>>>>>> recursively refer to the `enum`? >>>>>>>>>> This question also applies to access modifiers on extensions. So, >>>>>>>>>> what is it supposed to do? Change the default access modifier from >>>>>>>>>> `internal` to whatever I specify? That's just confusing, reduces >>>>>>>>>> readability and the syntactic gain is marginal at best. >>>>>>>>>> If the `indirect` confusion becomes real, I'd suggest getting rid of >>>>>>>>>> `indirect enum` and using `indirect case` instead. >>>>>>>>>> >>>>>>>>>>> On Jun 11, 2017, at 11:05 AM, Adrian Zubarev via swift-evolution >>>>>>>>>>> <swift-evolution@swift.org> wrote: >>>>>>>>>>> >>>>>>>>>>> The proposal is looking good to me. :) It will also enable easy >>>>>>>>>>> support for custom views using XIBs in iOS development without >>>>>>>>>>> unnecessary view nesting. >>>>>>>>>>> >>>>>>>>>>> For instance the function from this example >>>>>>>>>>> https://stackoverflow.com/a/43123783/4572536 could be used directly >>>>>>>>>>> inside an init: >>>>>>>>>>> >>>>>>>>>>> class MyView : UIView { >>>>>>>>>>> >>>>>>>>>>> indirect init() { >>>>>>>>>>> return MyView.instantiateFromXib() >>>>>>>>>>> // Or after SR-0068 >>>>>>>>>>> return Self.instantiateFromXib() >>>>>>>>>>> } >>>>>>>>>>> } >>>>>>>>>>> There is still one little thing that bothers me, it might be a >>>>>>>>>>> little bit confusing to have two different meanings of indirect on >>>>>>>>>>> enums. >>>>>>>>>>> >>>>>>>>>>> indirect enum ArithmeticExpression { >>>>>>>>>>> case number(Int) >>>>>>>>>>> case addition(ArithmeticExpression, ArithmeticExpression) >>>>>>>>>>> case multiplication(ArithmeticExpression, ArithmeticExpression) >>>>>>>>>>> >>>>>>>>>>> // This might makes no sense, but it would still be possible >>>>>>>>>>> after >>>>>>>>>>> // this proposal. >>>>>>>>>>> indirect init(other: ArithmeticExpression) { >>>>>>>>>>> return other >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> // Furthermore if the keyboard is applied to the enum >>>>>>>>>>> // directly all other `indirect` uses are inferred. >>>>>>>>>>> // Will this be implicitly `indirect` because of the previous >>>>>>>>>>> fact? >>>>>>>>>>> init() { … } >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Adrian Zubarev >>>>>>>>>>> Sent with Airmail >>>>>>>>>>> >>>>>>>>>>> Am 11. Juni 2017 um 00:38:56, Riley Testut via swift-evolution >>>>>>>>>>> (swift-evolution@swift.org) schrieb: >>>>>>>>>>> >>>>>>>>>>>> Awesome! Updated my proposal to include what I believed to be the >>>>>>>>>>>> relevant portions of your indirect initializer idea. Let me know >>>>>>>>>>>> if there’s anything I missed or should change :-) >>>>>>>>>>>> >>>>>>>>>>>> https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md >>>>>>>>>>>> >>>>>>>>>>>>> On Jun 10, 2017, at 12:43 PM, Gor Gyolchanyan >>>>>>>>>>>>> <g...@gyolchanyan.com> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>> Hi, Riley! >>>>>>>>>>>>> >>>>>>>>>>>>> I think that's a great idea! We can merge the second part of my >>>>>>>>>>>>> proposal (the `indirect init`) into your one and refine and >>>>>>>>>>>>> consolidate the prerequisite proposal (about returning from >>>>>>>>>>>>> `init` and possibly in-place member initializers) and bunch them >>>>>>>>>>>>> up into a proposal cluster (the way swift coders did). >>>>>>>>>>>>> Feel free to tear out any chunks from my proposal, while I think >>>>>>>>>>>>> about a more in-depth rationale about revamping initialization >>>>>>>>>>>>> syntax. 🙂 >>>>>>>>>>>>> >>>>>>>>>>>>>> On Jun 10, 2017, at 8:36 PM, Riley Testut >>>>>>>>>>>>>> <rileytes...@gmail.com> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Gor 👋 >>>>>>>>>>>>>> >>>>>>>>>>>>>> I’m very much in fan of a unified initialization syntax. I >>>>>>>>>>>>>> submitted my own proposal for factory initializers a while back, >>>>>>>>>>>>>> but since it wasn’t a focus of Swift 3 or 4 I haven’t followed >>>>>>>>>>>>>> up on it recently. In the time since last working on it, I came >>>>>>>>>>>>>> to my own conclusion that rather than focusing on factory >>>>>>>>>>>>>> initialization, the overall initialization process should be >>>>>>>>>>>>>> simplified, which I’m glad to see someone else has realized as >>>>>>>>>>>>>> well :-) >>>>>>>>>>>>>> >>>>>>>>>>>>>> Here’s my proposal for reference: >>>>>>>>>>>>>> https://github.com/apple/swift-evolution/pull/247/commits/58b5a93b322aae998eb40574dee15fe54323de2e >>>>>>>>>>>>>> Originally I used the “factory” keyword, but I think your >>>>>>>>>>>>>> “indirect” keyword may be a better fit (since it has precedent >>>>>>>>>>>>>> in the language and is not limited to “just” being about factory >>>>>>>>>>>>>> initialization). To divide your proposal up into smaller pieces >>>>>>>>>>>>>> for review, maybe we could update my proposal to use your >>>>>>>>>>>>>> indirect keyword, and then start a separate topic/proposal for >>>>>>>>>>>>>> the remaining aspects of your proposal? I agree that splitting >>>>>>>>>>>>>> it into smaller chunks may be better for the process. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Let me know what you think! >>>>>>>>>>>>>> >>>>>>>>>>>>>> Riley >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Jun 10, 2017, at 3:33 AM, Gor Gyolchanyan via >>>>>>>>>>>>>>>> swift-evolution <swift-evolution@swift.org> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> This is a very interesting read. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Thanks you! I tried to make it as clear and detailed as >>>>>>>>>>>>>>> possible. 🙂 >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> We did not discuss the 'indirect' idea at all on this list. >>>>>>>>>>>>>>>> Did you come up with it just now? In any case, my suggestion >>>>>>>>>>>>>>>> as to moving forward would be this: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I was writing the proposal and was just about to write `factory >>>>>>>>>>>>>>> init`, when it occurred to me: enums already have a keyword >>>>>>>>>>>>>>> that does something very similar. It seemed to me that an >>>>>>>>>>>>>>> initializer that doesn't initialize the instance in-place, but >>>>>>>>>>>>>>> returns a completely separate instance from somewhere else, is >>>>>>>>>>>>>>> kinda "indirectly" initializing the instance. Plus, the already >>>>>>>>>>>>>>> established keyword and its semantic would reduce the learning >>>>>>>>>>>>>>> curve for this new feature and separate it from a single >>>>>>>>>>>>>>> specific use case (the "factory method" pattern). >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - Do you feel that both halves of your draft (expanding >>>>>>>>>>>>>>>> `return` in initializers, and `indirect` initializers) should >>>>>>>>>>>>>>>> absolutely be one proposal, or can they be separated? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I think the `return` can be easily implemented first, while >>>>>>>>>>>>>>> opening up an opportunity to later implement `indirect init`. >>>>>>>>>>>>>>> The reason why I unified them was that the `return` idea on its >>>>>>>>>>>>>>> own has very limited merit and could the thought of as a >>>>>>>>>>>>>>> low-priority cosmetic enhancement. I wouldn't want it to be >>>>>>>>>>>>>>> viewed that way because the primary purpose of that idea is to >>>>>>>>>>>>>>> enable `indirect init` (which Cocoa and Cocoa Touch developers >>>>>>>>>>>>>>> would be very happy about). >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> a) If they can be separated because each half has individual >>>>>>>>>>>>>>>> merit, then these ideas may be more likely to succeed as >>>>>>>>>>>>>>>> separate proposals, as each can be critiqued fully and judged >>>>>>>>>>>>>>>> independently as digestible units. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Very good point. The challenge is to correctly separate them, >>>>>>>>>>>>>>> without losing context in their respective proposals and >>>>>>>>>>>>>>> without bleeding the proposals into each other. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> b) If you intend to tackle all your ideas all at once, that's >>>>>>>>>>>>>>>> going to be a much bigger change--in terms of review effort, >>>>>>>>>>>>>>>> likely bikeshedding, and implementation effort. It'll probably >>>>>>>>>>>>>>>> be best to solicit initial feedback on this list first about >>>>>>>>>>>>>>>> `indirect` initializers, even if just to familiarize the >>>>>>>>>>>>>>>> community with the idea, before launching into a pitch of the >>>>>>>>>>>>>>>> whole proposal. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I'd never send a pull request to swift-evolution without >>>>>>>>>>>>>>> thoroughly discussing it here. I just though, if I'm going to >>>>>>>>>>>>>>> write a whole proposal with examples and motivation, it would >>>>>>>>>>>>>>> be easier to demonstrate it and discuss in with the community >>>>>>>>>>>>>>> If I just went ahead and wrote the whole thing and sent the >>>>>>>>>>>>>>> link. This way it would be clearer to the reader and the >>>>>>>>>>>>>>> discussed changes would be accurately reflected by the commits >>>>>>>>>>>>>>> I'd make to my proposal. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Original Message >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Jun 10, 2017, at 2:38 AM, Daryle Walker via swift-evolution >>>>>>>>>>>>>>>> <swift-evolution@swift.org> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Fri, Jun 9, 2017 at 5:32 PM, Gor Gyolchanyan >>>>>>>>>>>>>>>>> <g...@gyolchanyan.com> wrote: >>>>>>>>>>>>>>>>> Forked swift-evolution, created a draft proposal: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> https://github.com/technogen-gg/swift-evolution/blob/master/proposals/NNNN-uniform-initialization.md >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> This is my first proposal, so I might have missed something >>>>>>>>>>>>>>>>> or composed it wrong, so please feel free to comment, fork >>>>>>>>>>>>>>>>> and send pull requests. 🙂 >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> This is a very interesting read. We did not discuss the >>>>>>>>>>>>>>>> 'indirect' idea at all on this list. Did you come up with it >>>>>>>>>>>>>>>> just now? In any case, my suggestion as to moving forward >>>>>>>>>>>>>>>> would be this: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - Do you feel that both halves of your draft (expanding >>>>>>>>>>>>>>>> `return` in initializers, and `indirect` initializers) should >>>>>>>>>>>>>>>> absolutely be one proposal, or can they be separated? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> a) If they can be separated because each half has individual >>>>>>>>>>>>>>>> merit, then these ideas may be more likely to succeed as >>>>>>>>>>>>>>>> separate proposals, as each can be critiqued fully and judged >>>>>>>>>>>>>>>> independently as digestible units. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> b) If you intend to tackle all your ideas all at once, that's >>>>>>>>>>>>>>>> going to be a much bigger change--in terms of review effort, >>>>>>>>>>>>>>>> likely bikeshedding, and implementation effort. It'll probably >>>>>>>>>>>>>>>> be best to solicit initial feedback on this list first about >>>>>>>>>>>>>>>> `indirect` initializers, even if just to familiarize the >>>>>>>>>>>>>>>> community with the idea, before launching into a pitch of the >>>>>>>>>>>>>>>> whole proposal. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Jun 9, 2017, at 3:24 PM, Xiaodi Wu <xiaodi...@gmail.com> >>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Cool. I have reservations about idea #3, but we can tackle >>>>>>>>>>>>>>>>>> that another day. (Real life things beckon.) But suffice it >>>>>>>>>>>>>>>>>> to say that I now really, really like your idea #2. >>>>>>>>>>>>>>>>>> On Fri, Jun 9, 2017 at 08:06 Gor Gyolchanyan >>>>>>>>>>>>>>>>>> <g...@gyolchanyan.com> wrote: >>>>>>>>>>>>>>>>>>> You know, come to think of it, I totally agree, and here's >>>>>>>>>>>>>>>>>>> why: >>>>>>>>>>>>>>>>>>> A normal initializer (if #2 is accepted) would >>>>>>>>>>>>>>>>>>> *conceptually* have the signature: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> mutating func `init`(...) -> Self >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Which would mean that both `self` and the returned result >>>>>>>>>>>>>>>>>>> are non-optional. >>>>>>>>>>>>>>>>>>> A failable initializer could then have the signature: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> mutating func `init`() -> Self? >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Which would make the returned result optional, but leave >>>>>>>>>>>>>>>>>>> `self` non-optional. >>>>>>>>>>>>>>>>>>> This would make `return nil` less out-of-place, like you >>>>>>>>>>>>>>>>>>> said, while still leaving `self` as a set-exactly-once >>>>>>>>>>>>>>>>>>> `inout Self`. >>>>>>>>>>>>>>>>>>> A factory initializer would then have the signature: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> static func `init`(...) -> Self >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> or in case of a failable factory initializer: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> static func `init`(...) -> Self? >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Which would still make sense with the now legal `return >>>>>>>>>>>>>>>>>>> ...` syntax, while adding the restriction of not having any >>>>>>>>>>>>>>>>>>> `self` at all. >>>>>>>>>>>>>>>>>>> So, annotating the initializer with the keyword `factory` >>>>>>>>>>>>>>>>>>> would cause it to change the signature as well as remove >>>>>>>>>>>>>>>>>>> any compiler assumptions about the dynamic type of the >>>>>>>>>>>>>>>>>>> returned instance. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> In addition, idea #3 would be available for more >>>>>>>>>>>>>>>>>>> deterministic in-place initialization. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Jun 9, 2017, at 2:47 PM, Xiaodi Wu >>>>>>>>>>>>>>>>>>>> <xiaodi...@gmail.com> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Fri, Jun 9, 2017 at 07:33 Gor Gyolchanyan >>>>>>>>>>>>>>>>>>>>> <g...@gyolchanyan.com> wrote: >>>>>>>>>>>>>>>>>>>>> So far, we've discussed two ways of interpreting `self = >>>>>>>>>>>>>>>>>>>>> nil`, both of which have a sensible solution, in my >>>>>>>>>>>>>>>>>>>>> opinion: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> 1. It's a special rule like you said, which can be seen >>>>>>>>>>>>>>>>>>>>> as counter-intuitive, but recall that `return nil` is >>>>>>>>>>>>>>>>>>>>> just as much of a special rule and is also largely >>>>>>>>>>>>>>>>>>>>> counter-intuitive. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> `return nil` is “special,” but it doesn’t conflict with >>>>>>>>>>>>>>>>>>>> any other syntax because the initializer notionally has no >>>>>>>>>>>>>>>>>>>> return value. Personally, I have always disliked `return >>>>>>>>>>>>>>>>>>>> nil` in failable initializers for that reason, but I >>>>>>>>>>>>>>>>>>>> couldn’t come up with a better alternative. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Your proposed idea to allow returning any value is >>>>>>>>>>>>>>>>>>>> interesting because, in the case of a failable >>>>>>>>>>>>>>>>>>>> initializer, `return nil` continues to have the same >>>>>>>>>>>>>>>>>>>> meaning if we consider the return value of the initializer >>>>>>>>>>>>>>>>>>>> to be of type `Self?`. For that reason, I think your idea >>>>>>>>>>>>>>>>>>>> #2 is quite clever, and it would go a long way in making >>>>>>>>>>>>>>>>>>>> `return nil` a lot less odd. It also increases the >>>>>>>>>>>>>>>>>>>> expressivity of initializers because it allows one to set >>>>>>>>>>>>>>>>>>>> the value of self and also return in one statement, >>>>>>>>>>>>>>>>>>>> clearly demonstrating the intention that no other code in >>>>>>>>>>>>>>>>>>>> the initializer should be run before returning. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> For all of those reasons, I think idea #2 is a winning >>>>>>>>>>>>>>>>>>>> idea. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> The benefit of `self = nil` is that it's much more in >>>>>>>>>>>>>>>>>>>>> line with initialization semantics, it provides more >>>>>>>>>>>>>>>>>>>>> uniform syntax and it's a bit less restrictive. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> 2. It's an `inout Self!`, like Greg said, which can be >>>>>>>>>>>>>>>>>>>>> seen as more cumbersome. Implicitly unwrapped optionals >>>>>>>>>>>>>>>>>>>>> are a bit difficult, but this "variation" of it is much >>>>>>>>>>>>>>>>>>>>> more restrictive then the normal ones, because unlike >>>>>>>>>>>>>>>>>>>>> normal implicitly unwrapped optionals, this one cannot be >>>>>>>>>>>>>>>>>>>>> accessed after being assigned nil (and it also cannot be >>>>>>>>>>>>>>>>>>>>> indirectly assigned `nil`, because escaping `self` is not >>>>>>>>>>>>>>>>>>>>> allowed before full initialization), so there is only one >>>>>>>>>>>>>>>>>>>>> possible place it can be set to nil and that's directly >>>>>>>>>>>>>>>>>>>>> in the initializer. This means that `self` can be safely >>>>>>>>>>>>>>>>>>>>> treated as `inout Self` before being set to nil (and >>>>>>>>>>>>>>>>>>>>> after being set to nil, it doesn't matter any more >>>>>>>>>>>>>>>>>>>>> because you aren't allowed to access it, due to not being >>>>>>>>>>>>>>>>>>>>> fully initialized). >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> I have to say, I don’t like either of these explanations >>>>>>>>>>>>>>>>>>>> at all. I think having a “special” IUO is a difficult >>>>>>>>>>>>>>>>>>>> sell; it is just conceptually too complicated, and I don’t >>>>>>>>>>>>>>>>>>>> agree that it gains you much. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> By your own admission, `self = nil` is wonky, and making >>>>>>>>>>>>>>>>>>>> the language wonkier because it currently has a parallel >>>>>>>>>>>>>>>>>>>> wonky feature in `return nil` seems like the wrong way to >>>>>>>>>>>>>>>>>>>> go. In addition, there’s nothing gained here that cannot >>>>>>>>>>>>>>>>>>>> be done with a defer statement; of course, defer >>>>>>>>>>>>>>>>>>>> statements might not be very elegant, but it would >>>>>>>>>>>>>>>>>>>> certainly be less wonky than inventing a new variation on >>>>>>>>>>>>>>>>>>>> an IUO to allow assignment of nil to self... For those >>>>>>>>>>>>>>>>>>>> reasons, I conclude that I’m not excited about your idea >>>>>>>>>>>>>>>>>>>> #1. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Overall, I'd go with #2 because it involves much less >>>>>>>>>>>>>>>>>>>>> confusing magic and the restrictions of `self as inout >>>>>>>>>>>>>>>>>>>>> Self!` are imposed by already existing and >>>>>>>>>>>>>>>>>>>>> well-understood initialization logic, so the provided >>>>>>>>>>>>>>>>>>>>> guarantees don't really come at the cost of much clarity. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> On Jun 9, 2017, at 2:23 PM, Xiaodi Wu >>>>>>>>>>>>>>>>>>>>>> <xiaodi...@gmail.com> wrote: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> On Fri, Jun 9, 2017 at 07:12 Gor Gyolchanyan >>>>>>>>>>>>>>>>>>>>>>> <g...@gyolchanyan.com> wrote: >>>>>>>>>>>>>>>>>>>>>>> I think a good approach would be to have `self = nil` >>>>>>>>>>>>>>>>>>>>>>> only mean `the initializer is going to fail` because if >>>>>>>>>>>>>>>>>>>>>>> your type is ExpressibleByNilLiteral, it means that the >>>>>>>>>>>>>>>>>>>>>>> `nil` of your type already carries the same meaning as >>>>>>>>>>>>>>>>>>>>>>> if your type was not ExpressibleByNilLiteral and was an >>>>>>>>>>>>>>>>>>>>>>> optional instead, so having a failable initializer >>>>>>>>>>>>>>>>>>>>>>> doesn't really make sense in that case (since you >>>>>>>>>>>>>>>>>>>>>>> could've initialized `self` to its own `nil` in case of >>>>>>>>>>>>>>>>>>>>>>> failure). Still, some valid use cases may exist, so the >>>>>>>>>>>>>>>>>>>>>>> natural (and quite intuitive) way to circumvent this >>>>>>>>>>>>>>>>>>>>>>> would be to call `self.init(nilLiteral: ())` directly. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> So you would create a special rule that `self = nil` >>>>>>>>>>>>>>>>>>>>>> means a different thing in an initializer than it does >>>>>>>>>>>>>>>>>>>>>> in a function? Essentially, then, you’re creating your >>>>>>>>>>>>>>>>>>>>>> own variation on an implicitly unwrapped optional, where >>>>>>>>>>>>>>>>>>>>>> `self` is of type `inout Self?` for assignment in >>>>>>>>>>>>>>>>>>>>>> initializers only but not for any other purpose. >>>>>>>>>>>>>>>>>>>>>> Implicitly unwrapped optionals are hard to reason about, >>>>>>>>>>>>>>>>>>>>>> and having a variation on it would be even harder to >>>>>>>>>>>>>>>>>>>>>> understand. I don’t think this is a workable design. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> It might be possible to have `self` be of type `inout >>>>>>>>>>>>>>>>>>>>>> Self?`; however, I do think Greg is right that it would >>>>>>>>>>>>>>>>>>>>>> create more boilerplate than the current situation. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> On Jun 9, 2017, at 2:07 PM, Xiaodi Wu >>>>>>>>>>>>>>>>>>>>>>>> <xiaodi...@gmail.com> wrote: >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> On Fri, Jun 9, 2017 at 06:56 Gor Gyolchanyan >>>>>>>>>>>>>>>>>>>>>>>>> <g...@gyolchanyan.com> wrote: >>>>>>>>>>>>>>>>>>>>>>>>> The type of `self` could remain `inout Self` inside >>>>>>>>>>>>>>>>>>>>>>>>> the failable initializer. The ability to assign nil >>>>>>>>>>>>>>>>>>>>>>>>> would be a compiler magic (much like `return nil` is >>>>>>>>>>>>>>>>>>>>>>>>> compiler magic) that is meant to introduce uniformity >>>>>>>>>>>>>>>>>>>>>>>>> to the initialization logic. >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> The idea is to define all different ways >>>>>>>>>>>>>>>>>>>>>>>>> initialization can take place and expand them to be >>>>>>>>>>>>>>>>>>>>>>>>> used uniformly on both `self` and all its members, as >>>>>>>>>>>>>>>>>>>>>>>>> well as remove the ways that do not make sense for >>>>>>>>>>>>>>>>>>>>>>>>> their purpose. >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> Currently, there are 3 ways of initializing self as a >>>>>>>>>>>>>>>>>>>>>>>>> whole: >>>>>>>>>>>>>>>>>>>>>>>>> 1. delegating initializer >>>>>>>>>>>>>>>>>>>>>>>>> 2. assigning to self >>>>>>>>>>>>>>>>>>>>>>>>> 3. returning nil >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> #1: The delegating initializer is pretty much perfect >>>>>>>>>>>>>>>>>>>>>>>>> at this point, in my opinion, so no changes there. >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> #2: The only exception in assigning to self is the >>>>>>>>>>>>>>>>>>>>>>>>> `nil` inside failable initializers. >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> #3: The only thing that can be returned from an >>>>>>>>>>>>>>>>>>>>>>>>> initializer is `nil`, which is compiler magic, so we >>>>>>>>>>>>>>>>>>>>>>>>> can thing of it as a misnomer (because we aren't >>>>>>>>>>>>>>>>>>>>>>>>> really **returning** anything). >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> If, for a second, we forget about potential factory >>>>>>>>>>>>>>>>>>>>>>>>> initializers, returning anything from an initializer >>>>>>>>>>>>>>>>>>>>>>>>> doesn't make much sense, because an initializer is >>>>>>>>>>>>>>>>>>>>>>>>> conceptually meant to bring an existing object in >>>>>>>>>>>>>>>>>>>>>>>>> memory to a type-specific valid state. This semantic >>>>>>>>>>>>>>>>>>>>>>>>> was very explicitly in Objective-C with `[[MyType >>>>>>>>>>>>>>>>>>>>>>>>> alloc] init]`. Especially since even syntactically, >>>>>>>>>>>>>>>>>>>>>>>>> the initializer does not specify any return type, the >>>>>>>>>>>>>>>>>>>>>>>>> idea of returning from an initializer is >>>>>>>>>>>>>>>>>>>>>>>>> counter-intuitive both syntactically and semantically. >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> The actual *behavior* of `return nil` is very >>>>>>>>>>>>>>>>>>>>>>>>> sensible, so the behavior, I imagine `self = nil`, >>>>>>>>>>>>>>>>>>>>>>>>> would largely mean the same (except not needed to >>>>>>>>>>>>>>>>>>>>>>>>> return immediately and allowing non-self-accessing >>>>>>>>>>>>>>>>>>>>>>>>> code to be executed before return). Being able to >>>>>>>>>>>>>>>>>>>>>>>>> assign `nil` to a non-optional >>>>>>>>>>>>>>>>>>>>>>>>> (ExpressibleByNilLiteral doesn't count) may feel a >>>>>>>>>>>>>>>>>>>>>>>>> bit wonky, >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> What happens when Self is ExpressibleByNilLiteral and >>>>>>>>>>>>>>>>>>>>>>>> you want to initialize self to nil? That is what `self >>>>>>>>>>>>>>>>>>>>>>>> = nil` means if `self` is of type `inout Self`. If >>>>>>>>>>>>>>>>>>>>>>>> `self` is of type `inout Self` and Self is not >>>>>>>>>>>>>>>>>>>>>>>> ExpressibleByNilLiteral, then it must be an error to >>>>>>>>>>>>>>>>>>>>>>>> assign nil to self. Anything else does not make sense, >>>>>>>>>>>>>>>>>>>>>>>> unless `self` is of type `inout Self?`. >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> but not as wonky as returning nil from something that >>>>>>>>>>>>>>>>>>>>>>>>> is meant to initialize an object in-place and doesn't >>>>>>>>>>>>>>>>>>>>>>>>> look like it should return anything. >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> # Factory Initializers >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> In case of factory initializers, the much discussed >>>>>>>>>>>>>>>>>>>>>>>>> `factory init` syntax could completely flip this >>>>>>>>>>>>>>>>>>>>>>>>> logic, but making the initializer essentially a >>>>>>>>>>>>>>>>>>>>>>>>> static function that returns an object. In this case >>>>>>>>>>>>>>>>>>>>>>>>> the initializer could be made to specify the return >>>>>>>>>>>>>>>>>>>>>>>>> type (that is the supertype of all possible >>>>>>>>>>>>>>>>>>>>>>>>> factory-created objects) and assigning to self would >>>>>>>>>>>>>>>>>>>>>>>>> be forbidden because there is not self yet: >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> extension MyProtocol { >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> public factory init(weCool: Bool) -> MyProtocol { >>>>>>>>>>>>>>>>>>>>>>>>> self = MyImpl() // error: cannot assign to `self` in >>>>>>>>>>>>>>>>>>>>>>>>> a factory initializer >>>>>>>>>>>>>>>>>>>>>>>>> self.init(...) // error: cannot make a delegating >>>>>>>>>>>>>>>>>>>>>>>>> initializer call in a factory initializer >>>>>>>>>>>>>>>>>>>>>>>>> if weCool { >>>>>>>>>>>>>>>>>>>>>>>>> return MyCoolImpl() >>>>>>>>>>>>>>>>>>>>>>>>> } else { >>>>>>>>>>>>>>>>>>>>>>>>> return MyUncoolImpl() >>>>>>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> # In-place Member Initializers >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> In addition, member initialization currently is only >>>>>>>>>>>>>>>>>>>>>>>>> possible with #2 (as in `self.member = value`), which >>>>>>>>>>>>>>>>>>>>>>>>> could be extended in a non-factory initializer to be >>>>>>>>>>>>>>>>>>>>>>>>> initializable in-place like this: >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> self.member.init(...) >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> This would compliment the delegating initialization >>>>>>>>>>>>>>>>>>>>>>>>> syntax, while giving a more reliable performance >>>>>>>>>>>>>>>>>>>>>>>>> guarantee that this member will not be >>>>>>>>>>>>>>>>>>>>>>>>> copy-initialized. >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> On Jun 9, 2017, at 1:32 PM, Xiaodi Wu >>>>>>>>>>>>>>>>>>>>>>>>>> <xiaodi...@gmail.com> wrote: >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> If `self` is not of type `inout Self?`, then what is >>>>>>>>>>>>>>>>>>>>>>>>>> the type of `self` such that you may assign it a >>>>>>>>>>>>>>>>>>>>>>>>>> value of `nil`? >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> It certainly cannot be of type `inout Self`, unless >>>>>>>>>>>>>>>>>>>>>>>>>> `Self` conforms to `ExpressibleByNilLiteral`, in >>>>>>>>>>>>>>>>>>>>>>>>>> which case you are able to assign `self = nil` an >>>>>>>>>>>>>>>>>>>>>>>>>> unlimited number of times–but that has a totally >>>>>>>>>>>>>>>>>>>>>>>>>> different meaning. >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> Could `self` be of type `inout Self!`? Now that >>>>>>>>>>>>>>>>>>>>>>>>>> implicitly unwrapped optionals are no longer their >>>>>>>>>>>>>>>>>>>>>>>>>> own type, I’m not sure that’s possible. But even if >>>>>>>>>>>>>>>>>>>>>>>>>> it were, that seems unintuitive and potentially >>>>>>>>>>>>>>>>>>>>>>>>>> error-prone. >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> So I think Greg is quite right that, to enable this >>>>>>>>>>>>>>>>>>>>>>>>>> feature, `self` would have to be of type `inout >>>>>>>>>>>>>>>>>>>>>>>>>> Self?`–which is intriguing but potentially more >>>>>>>>>>>>>>>>>>>>>>>>>> boilerplatey than the status quo. >>>>>>>>>>>>>>>>>>>>>>>>>>> On Fri, Jun 9, 2017 at 05:24 Gor Gyolchanyan via >>>>>>>>>>>>>>>>>>>>>>>>>>> swift-evolution <swift-evolution@swift.org> wrote: >>>>>>>>>>>>>>>>>>>>>>>>>>> Good point, but not necessarily. >>>>>>>>>>>>>>>>>>>>>>>>>>> Since you cannot access `self` before it being >>>>>>>>>>>>>>>>>>>>>>>>>>> fully initialized and since `self` can only be >>>>>>>>>>>>>>>>>>>>>>>>>>> initialized once, this would mean that after `self >>>>>>>>>>>>>>>>>>>>>>>>>>> = nil`, you won't be allowed to access `self` in >>>>>>>>>>>>>>>>>>>>>>>>>>> your initializer at all.You'll be able to do any >>>>>>>>>>>>>>>>>>>>>>>>>>> potential, cleanup though. >>>>>>>>>>>>>>>>>>>>>>>>>>> Also, since there can be only one `self = nil`, >>>>>>>>>>>>>>>>>>>>>>>>>>> there's no reason to treat `self` as `inout Self?`, >>>>>>>>>>>>>>>>>>>>>>>>>>> because the only place it can be `nil` is the place >>>>>>>>>>>>>>>>>>>>>>>>>>> it cannot be accessed any more. >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Jun 9, 2017, at 7:45 AM, Greg Parker >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <gpar...@apple.com> wrote: >>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Jun 8, 2017, at 5:09 AM, Gor Gyolchanyan via >>>>>>>>>>>>>>>>>>>>>>>>>>>>> swift-evolution <swift-evolution@swift.org> wrote: >>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1. Arbitrary `self` Assignments In Intializers >>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>> The first ideas is to allow `self = nil` inside >>>>>>>>>>>>>>>>>>>>>>>>>>>>> failable initializers (essentially making `self` >>>>>>>>>>>>>>>>>>>>>>>>>>>>> look like `inout Self?` instead of `inout Self` >>>>>>>>>>>>>>>>>>>>>>>>>>>>> with magical `return nil`), so that all >>>>>>>>>>>>>>>>>>>>>>>>>>>>> initializers uniformly can be written in `self = >>>>>>>>>>>>>>>>>>>>>>>>>>>>> ...` form for clarity and convenience purposes. >>>>>>>>>>>>>>>>>>>>>>>>>>>>> This should, theoretically, be nothing but a >>>>>>>>>>>>>>>>>>>>>>>>>>>>> `defer { return nil }` type of rewrite, so I >>>>>>>>>>>>>>>>>>>>>>>>>>>>> don't see any major difficulties implementing >>>>>>>>>>>>>>>>>>>>>>>>>>>>> this. This is especially useful for >>>>>>>>>>>>>>>>>>>>>>>>>>>>> failable-initializing enums where the main switch >>>>>>>>>>>>>>>>>>>>>>>>>>>>> simply assigns to self in all cases and the rest >>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the initializer does some post-processing. >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> I don't see how to avoid source incompatibility >>>>>>>>>>>>>>>>>>>>>>>>>>>> and uglification of failable initializer >>>>>>>>>>>>>>>>>>>>>>>>>>>> implementations here. Allowing `self = nil` inside >>>>>>>>>>>>>>>>>>>>>>>>>>>> a failable initializer would require `self` to be >>>>>>>>>>>>>>>>>>>>>>>>>>>> an optional. That in turn would require every use >>>>>>>>>>>>>>>>>>>>>>>>>>>> of `self` in the initializer to be nil-checked or >>>>>>>>>>>>>>>>>>>>>>>>>>>> forced. I don't think that loss everywhere >>>>>>>>>>>>>>>>>>>>>>>>>>>> outweighs the gain of `self = nil` in some places. >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>>>>>>> Greg Parker gpar...@apple.com Runtime >>>>>>>>>>>>>>>>>>>>>>>>>>>> Wrangler >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>>>>>>>>>>>>>> swift-evolution mailing list >>>>>>>>>>>>>>>>>>>>>>>>>>> swift-evolution@swift.org >>>>>>>>>>>>>>>>>>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>> swift-evolution mailing list >>>>>>>>>>>>>>> swift-evolution@swift.org >>>>>>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>> swift-evolution mailing list >>>>>>>>>>>> swift-evolution@swift.org >>>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> _______________________________________________ >>>>>>>>>>> swift-evolution mailing list >>>>>>>>>>> swift-evolution@swift.org >>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> swift-evolution mailing list >>>>>>>>> swift-evolution@swift.org >>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> >> > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution