Can you point me towards the changes to the `self.` so I can catch up to what I might have missed? I remember it causing trouble, especially with things like this:
extension MyType: ExpressibleByIntegerLiteral { public typealias IntegerLiteralType = UInt64 public init(initegerLiteral literal: IntegerLiteralType) { self.uint64Value = literal // error: Cannot convert from IntegerLiteralType (a.k.a. Int) to UInt64 } } It clearly preferred the global `IntegerLiteralType` over mine and replacing the signature with `(integerLiteral literal: Self.IntegerLiteralType)` fixed it. There have been numerous examples like this. If you make a protocol, which you intend to fully automatically conform to another protocol (by implementing all its requirements in a protocol extension), this "conformance" can silently fail due to ambiguities like this and you won't catch it until you conform to this protocol and find a weird error. It's even more confusing in generic function constraints: extension theUltimateAnswerToLifeUniverseAndEverything<A>() -> A where A: ExpressibleByIntegerLiteral, IntegerLiteralType == IntMax { return 42 } Can you honestly say that from the first glance, it's immediately obvious to you which one of the `IntegerLiteralType ` this is referring to? Regarding access modifiers on extensions and `inout enum`, I agree: that's an unnecessary complication of the lexical structure that introduces a lot of confusion and provides very questionable gain. > On Jun 11, 2017, at 11:43 AM, Adrian Zubarev > <adrian.zuba...@devandartist.com> wrote: > > self. is a different story. It’s absence has become quite popular out in the > wild and it’s becoming even more optional in Swift 4. A week or two ago Slava > Pestov said on twitter that he has fixed several bugs that made self. even > more optional though the whole language. > > Personally I don’t care if other people are using this convenience, I’ll let > them have that option :-) , but I simply cannot get along with the idea that > there could a global variable or a function that has the exact same signature > as one of the type members, which could lead to unexpected bugs which are > really hard to track. > > If I would granted the chance to tackle again the access modifier on > extensions, I’d do it and try to remove that feature from the language. I’m > not using it, I won’t ever use it and I haven’t seen any *good* swift code > using it. It’s just too much sugar if you ask me. > > Same goes for indirect enum. How rare is it used? If it’s used how complex > are the enum cases that it cannot be applied on the cases only which needs it? > > > > > -- > Adrian Zubarev > Sent with Airmail > > Am 11. Juni 2017 um 10:30:29, Gor Gyolchanyan (g...@gyolchanyan.com > <mailto:g...@gyolchanyan.com>) schrieb: > >> There was another proposal that got rejected, which was about forcing the >> usage of `self.` on members. >> I pretty much *require* it in my code for two reasons: >> * The understandable requirement of `self.` in closures conflicts with the >> lack of `self.` in methods, which is confusing. >> * The ability to refer to globals and members in the same way is also making >> the code harder to read. >> >> The same goes for using `Self.` for associated types and type aliases inside >> protocols, because it's very easy to accidentally confuse them with global >> types, which would mess up the protocol. >> I know that this adds a bit of code, but it does not make the code less >> readable (in the contrary) and modern IDEs are very capable of code >> completion, which negates the problem of having to type more text manually. >> >> The argument agains this was something like "this is not worth sacrificing >> such a convenience". >> On the other hand, on numerous occasions I've heard another argument against >> a proposal that said "it's not worth gaining terseness by sacrificing >> clarity". >> >> This direct contradiction of priorities is worrying to me. >> >>> On Jun 11, 2017, at 11:21 AM, Adrian Zubarev >>> <adrian.zuba...@devandartist.com <mailto:adrian.zuba...@devandartist.com>> >>> 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 https://lists.swift.org/mailman/listinfo/swift-evolution