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 <xiaodi...@gmail.com> wrote: > > On Sun, Jun 11, 2017 at 3:49 PM, Riley Testut <rileytes...@gmail.com > <mailto:rileytes...@gmail.com>> 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 > <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> 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 <xiaodi...@gmail.com >>> <mailto:xiaodi...@gmail.com>> wrote: >>> >>> On Sun, Jun 11, 2017 at 12:43 PM, Gor Gyolchanyan <g...@gyolchanyan.com >>> <mailto: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 >>>> <mailto:xiaodi...@gmail.com>> wrote: >>>> >>>> On Sun, Jun 11, 2017 at 10:34 AM, Gor Gyolchanyan <g...@gyolchanyan.com >>>> <mailto: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 >>>>> <mailto:xiaodi...@gmail.com>> wrote: >>>>> >>>>> On Sun, Jun 11, 2017 at 8:49 AM, Gor Gyolchanyan <g...@gyolchanyan.com >>>>> <mailto: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 >>>>>> <mailto: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 <mailto: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 >>>>>> <mailto: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 <mailto: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 >>>>>>>> <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 <mailto: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 >>>>>>>>> >>>>>>>>> <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 >>>>>>>>>> <mailto: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 >>>>>>>>>>> <mailto: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 >>>>>>>>>>> >>>>>>>>>>> <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 <mailto: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 <mailto:swift-evolution@swift.org>> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>> On Fri, Jun 9, 2017 at 5:32 PM, Gor Gyolchanyan >>>>>>>>>>>>> <g...@gyolchanyan.com <mailto: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 >>>>>>>>>>>>> >>>>>>>>>>>>> <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 >>>>>>>>>>>>>> <mailto: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 <mailto: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 >>>>>>>>>>>>>>> <mailto:xiaodi...@gmail.com>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Fri, Jun 9, 2017 at 07:33 Gor Gyolchanyan >>>>>>>>>>>>>>> <g...@gyolchanyan.com <mailto: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 >>>>>>>>>>>>>>>> <mailto:xiaodi...@gmail.com>> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Fri, Jun 9, 2017 at 07:12 Gor Gyolchanyan >>>>>>>>>>>>>>>> <g...@gyolchanyan.com <mailto: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 >>>>>>>>>>>>>>>>> <mailto:xiaodi...@gmail.com>> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Fri, Jun 9, 2017 at 06:56 Gor Gyolchanyan >>>>>>>>>>>>>>>>> <g...@gyolchanyan.com <mailto: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 >>>>>>>>>>>>>>>>>> <mailto: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 >>>>>>>>>>>>>>>>>> <mailto: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 >>>>>>>>>>>>>>>>>>> <mailto:gpar...@apple.com>> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Jun 8, 2017, at 5:09 AM, Gor Gyolchanyan via >>>>>>>>>>>>>>>>>>>> swift-evolution <swift-evolution@swift.org >>>>>>>>>>>>>>>>>>>> <mailto: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 >>>>>>>>>>>>>>>>>>> <mailto:gpar...@apple.com> Runtime Wrangler >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>>>>> swift-evolution mailing list >>>>>>>>>>>>>>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>> swift-evolution mailing list >>>>>>>>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> swift-evolution mailing list >>>>>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> swift-evolution mailing list >>>>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>>> >>>>>> _______________________________________________ >>>>>> swift-evolution mailing list >>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>> >> >> _______________________________________________ >> swift-evolution mailing list >> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> <https://lists.swift.org/mailman/listinfo/swift-evolution> >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution