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