> Changing how Objective-C initializers are imported sounds like a big and > dangerous task, but factory initializers behave exactly how Objective-C > initializers behave, compared to Swift initializers. Importing them all as > `fatory` init wouldn't change the behavior in any way, only mark the > initializer as `factory`. However, it does look like Objective-C initializers > will have to be a special case, in order for non-factory initializers in > Swift to be able to override them.
IIRC, there is already special logic for handling Objective-C initializers from Swift; they are effectively implemented as if they were factory initializers. I still don’t think we need to explicitly mark them as factory though, as that would certainly be confusing to newcomers (and would mess with the convenience/required initializer chain). > We could just drop factory initializers in classes for now and start by only > adding them to protocols (which is incomparably easier) and see where this > goes first. I believe factory initializers are most powerful with classes, and since this would need to be solved anyway, I think we should move forward with it for all types + protocol extensions > On Jun 12, 2017, at 12:43 AM, Gor Gyolchanyan <[email protected]> wrote: > > I have thought of `static init`, but there are two problems with it: > * The `static`-ness of it is purely an implementational detail and is not > related to the purpose of these initializers. > * The term "static initializer" has another meaning in Objective-C (and other > languages) that initializes the type itself once at the start of the process. > > Changing how Objective-C initializers are imported sounds like a big and > dangerous task, but factory initializers behave exactly how Objective-C > initializers behave, compared to Swift initializers. Importing them all as > `fatory` init wouldn't change the behavior in any way, only mark the > initializer as `factory`. However, it does look like Objective-C initializers > will have to be a special case, in order for non-factory initializers in > Swift to be able to override them. > > *OR* > > The way initializers worked in Objective-C is the opposite of how they work > in Swift: `self = [super init]; self.member = value;` (not counting the NULL > checks). This allowed overriding them and delegating to them even though > they're essentially factory methods. The problem with this was that with > Objective-C's poor type safety, it was easy to forget to initialize the > members, but with Swift, there's a strong type system for that. What we could > do is to make Objective-C's factory initializers create the dynamic type > using NSObject's `init()` and have the subclass's factory initializer > initialize all its members *after" the instance is created. > > *OR* > > We could just drop factory initializers in classes for now and start by only > adding them to protocols (which is incomparably easier) and see where this > goes first. > >> On Jun 12, 2017, at 12:30 AM, Xiaodi Wu <[email protected] >> <mailto:[email protected]>> wrote: >> >> On Sun, Jun 11, 2017 at 3:49 PM, Riley Testut <[email protected] >> <mailto:[email protected]>> wrote: >> 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. >> >> I'm not expert enough on Obj-C interop issues to make insightful comments on >> this, but my naive impression here is that changing how _all_ Obj-C >> initializers are imported by default seems...risky? Perhaps a summary of how >> the compiler currently handles the issue is in order for this proposal, so >> as to enable readers to evaluate this change. >> >> • 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. >> >> Agree: `self` referring to a type is unprecedented when it's not a static >> method--this feels weird. If this is essential for the whole design, have >> you considered maybe just calling it `static init`? (This raises a >> potentially interesting thought about whether it'd make sense to also have a >> `class init`...) >> >> • 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. >> >> Hmm. That sounds workable and simpler, definitely. >> >> 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 >> <[email protected] <mailto:[email protected]>> wrote: >> >>> Here's the updated proposal: >>> >>> https://github.com/technogen-gg/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md >>> >>> <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 <[email protected] >>>> <mailto:[email protected]>> wrote: >>>> >>>> On Sun, Jun 11, 2017 at 12:43 PM, Gor Gyolchanyan <[email protected] >>>> <mailto:[email protected]>> 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 <[email protected] >>>>> <mailto:[email protected]>> wrote: >>>>> >>>>> On Sun, Jun 11, 2017 at 10:34 AM, Gor Gyolchanyan <[email protected] >>>>> <mailto:[email protected]>> 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 <[email protected] >>>>>> <mailto:[email protected]>> wrote: >>>>>> >>>>>> On Sun, Jun 11, 2017 at 8:49 AM, Gor Gyolchanyan <[email protected] >>>>>> <mailto:[email protected]>> 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 <[email protected] >>>>>>> <mailto:[email protected]>> 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 >>>>>>> <[email protected] <mailto:[email protected]>> 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 ([email protected] >>>>>>> <mailto:[email protected]>) 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 >>>>>>>>> <[email protected] <mailto:[email protected]>> 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 >>>>>>>>> <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 >>>>>>>>> ([email protected] <mailto:[email protected]>) >>>>>>>>> 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 >>>>>>>>>> >>>>>>>>>> <https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md> >>>>>>>>>>> On Jun 10, 2017, at 12:43 PM, Gor Gyolchanyan <[email protected] >>>>>>>>>>> <mailto:[email protected]>> 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 <[email protected] >>>>>>>>>>>> <mailto:[email protected]>> 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 >>>>>>>>>>>> >>>>>>>>>>>> <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 >>>>>>>>>>>>> <[email protected] <mailto:[email protected]>> >>>>>>>>>>>>> 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 >>>>>>>>>>>>>> <[email protected] <mailto:[email protected]>> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Fri, Jun 9, 2017 at 5:32 PM, Gor Gyolchanyan >>>>>>>>>>>>>> <[email protected] <mailto:[email protected]>> wrote: >>>>>>>>>>>>>> Forked swift-evolution, created a draft proposal: >>>>>>>>>>>>>> >>>>>>>>>>>>>> https://github.com/technogen-gg/swift-evolution/blob/master/proposals/NNNN-uniform-initialization.md >>>>>>>>>>>>>> >>>>>>>>>>>>>> <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 <[email protected] >>>>>>>>>>>>>>> <mailto:[email protected]>> 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 >>>>>>>>>>>>>>> <[email protected] <mailto:[email protected]>> 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 <[email protected] >>>>>>>>>>>>>>>> <mailto:[email protected]>> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Fri, Jun 9, 2017 at 07:33 Gor Gyolchanyan >>>>>>>>>>>>>>>> <[email protected] <mailto:[email protected]>> 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 <[email protected] >>>>>>>>>>>>>>>>> <mailto:[email protected]>> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Fri, Jun 9, 2017 at 07:12 Gor Gyolchanyan >>>>>>>>>>>>>>>>> <[email protected] <mailto:[email protected]>> 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 <[email protected] >>>>>>>>>>>>>>>>>> <mailto:[email protected]>> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Fri, Jun 9, 2017 at 06:56 Gor Gyolchanyan >>>>>>>>>>>>>>>>>> <[email protected] <mailto:[email protected]>> 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 <[email protected] >>>>>>>>>>>>>>>>>>> <mailto:[email protected]>> 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 <[email protected] >>>>>>>>>>>>>>>>>>> <mailto:[email protected]>> 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 <[email protected] >>>>>>>>>>>>>>>>>>>> <mailto:[email protected]>> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Jun 8, 2017, at 5:09 AM, Gor Gyolchanyan via >>>>>>>>>>>>>>>>>>>>> swift-evolution <[email protected] >>>>>>>>>>>>>>>>>>>>> <mailto:[email protected]>> 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 [email protected] >>>>>>>>>>>>>>>>>>>> <mailto:[email protected]> Runtime Wrangler >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>>>>>> swift-evolution mailing list >>>>>>>>>>>>>>>>>>> [email protected] <mailto:[email protected]> >>>>>>>>>>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>>>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>> swift-evolution mailing list >>>>>>>>>>>>> [email protected] <mailto:[email protected]> >>>>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> _______________________________________________ >>>>>>>>>> swift-evolution mailing list >>>>>>>>>> [email protected] <mailto:[email protected]> >>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>>>>> >>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> swift-evolution mailing list >>>>>>>>> [email protected] <mailto:[email protected]> >>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>>>> >>>>>>> _______________________________________________ >>>>>>> swift-evolution mailing list >>>>>>> [email protected] <mailto:[email protected]> >>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>> >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> [email protected] <mailto:[email protected]> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
