Looks good, but I have a few thoughts on it: * I think indirect initializers *shoud* be overridable, but only by other indirect initializers. This will allow subclasses of the factory to expand the factory method by adding new possible instances to return. * You did not include the specification of implementation details that I provided as well as C/Objective-C interoperability changes. * The proposal is formulated more like a personal opinion, rather then a formal specification. It sounds like a personal letter. I'd recommend writing it similarly as you'd write a wikipedia page.
> On Jun 11, 2017, at 1:12 AM, Riley Testut <rileytes...@gmail.com> wrote: > > 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 https://lists.swift.org/mailman/listinfo/swift-evolution