[swift-evolution] [Proposal Draft] partial initializers

David Owens II david at owensd.io
Mon Jan 11 22:33:39 CST 2016


> On Jan 11, 2016, at 5:43 PM, Matthew Johnson <matthew at anandabits.com> wrote:
> 
> 
>> On Jan 11, 2016, at 7:33 PM, David Owens II <david at owensd.io <mailto:david at owensd.io>> wrote:
>> 
>>> 
>>> On Jan 10, 2016, at 7:44 PM, Matthew Johnson via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>> I have always considered the Flexible Memberwise Initialization proposal to be just a first step (as evidenced by the many future enhancements it discussed).  Its review has inspired new ideas and helped to shape my vision of the best long-term solution.    My final thoughts about the review can be found here: https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160104/006176.html <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160104/006176.html>
>>> 
>>> Partial initializers is the second in a series of three proposals describing general features that can work together to form a complete solution.
>>> 
>>> The proposal drafts can be found at the following links:
>>> 
>>> * Parameter forwarding: https://github.com/anandabits/swift-evolution/blob/parameter-forwarding/proposals/NNNN-parameter-forwarding.md <https://github.com/anandabits/swift-evolution/blob/parameter-forwarding/proposals/NNNN-parameter-forwarding.md>
>>> * Partial initializers: https://github.com/anandabits/swift-evolution/blob/partial-initializers/proposals/NNNN-partial-initializers.md <https://github.com/anandabits/swift-evolution/blob/partial-initializers/proposals/NNNN-partial-initializers.md>
>>> * Property lists: https://github.com/anandabits/swift-evolution/blob/property-lists/proposals/NNNN-property-lists.md <https://github.com/anandabits/swift-evolution/blob/property-lists/proposals/NNNN-property-lists.md>
>>> 
>> 
>> The biggest drawback I see is that is doesn’t really address the ability to use normal functions to initialize the state of the type. For example, in order to implement a “reset” or “clear” mechanism, I still need to duplicate a bunch of init code.
>> 
>> class CFoo {
>>     private(set) var value: Int
>>     
>>     func reset() {
>>         value = 0
>>     }
>>     
>>     init() {
>>         // Really want to just call this...
>>         //reset()
>>         
>>         // But, instead, I need to duplicate the code from `reset()`
>>         value = 0
>>     }
>>     
>>     func inc() {
>>         ++value
>>     }
>> }
>> 
>> let c = CFoo()
>> c.inc()
>> c.value    // 1
>> c.reset()
>> c.value    // 0
>> 
>> 
>> Take the above code, the “init” functionality is really about putting the type in the correct state. I think I’d rather see a mechanism to make a non-initializer as adhering to the rules of an init() so that it could be used in multiple contexts. 
>> 
>> I think this modification makes your proposal much more interesting and applicable to more use cases.
>> 
> 
> That is a fair point.  
> 
> The reason I didn’t go that route has a lot to do with `let` properties.  It would feel weird to me to be assigning to a `let` in a non-init method (that is why I didn’t like Joe’s tuple property idea).  And a method that does that couldn’t be called any other time anyway.

Well, this is a limitation (assigning to lets) that convenience inits() have as well. Also, as it’s a function that is callable, it makes little sense to have `let` assignments in it anyway. So that limitation seems fine. The annotation would only be there to allow the compiler (and code authors) know that this method is intended to be allowed in the initialization rules, so some restrictions may apply.

> Maybe we could introduce partial inits as well as an attribute or decl modifier for methods that have similar behavior to partial inits, but are not allowed to assign to a `let` property (maybe @init).  I could add something along those lines to this proposal or it could be a separate follow-on proposal.
> 
> What do you think of that?  

What I’m saying is that you don’t need the partial inits anymore, you still need some of your rules, but the actual “partial init” would be replaced by this modifier on functions.

Maybe something like this:

    initializer func reset() {
        value1 = 0
    }

The “initializer” modifier would be your “partial init” modifier. For this to work though, you’d basically have to take the same limitation as convenience inits() today and disallow `let` values to be set. However, most of your other rules would apply to these.

Well… I guess there is this too:

>  Partial initializers receive an identifier, which avoids the need to rely on overloading to differentiate between partial initializers.

This would still remove the ability to use `let` assignments, but those functions could be allowed to be called like normal functions.

struct S {
  let a, b, c, d: Int
  partial init bAndC(i: Int = 10) {
    b = 10
    c = 20
  }
  init(i: Int) {
    a = i * 2
    d = i * 4
    bAndC.init()
  }
}

var s = S(12)
s.bAndC(1)

Again, you’ve have to remove the `let` assignments… 

Anyhow, just mostly thinking out loud at this point.

-David

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160111/df52c163/attachment.html>


More information about the swift-evolution mailing list