<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>I wrote a draft of a partial initializer proposal back in January or February of last year. &nbsp;If you're thinking of re-introducing that topic you might want to take a look at it. &nbsp;You can find it here:&nbsp;<a href="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</a>. &nbsp;There was some discussion on the list as well. &nbsp;You might want to look up that conversation in the archives. &nbsp;</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature"><br>Sent from my iPad</div><div><br>On Jun 25, 2017, at 2:24 PM, Robert Bennett via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><span>You’re right Xiaodi, I did not entirely think this through. However I think this could still work with another addition to the language: partial initializers. These would be treated as initializers are now (meaning, for instance, no reference to self until initialization is complete) except they would only need to initialize a subset of the instance variables before exiting. An initializer could then satisfy the requirement that all instance variables must be initialized by calling partial initializers.</span><br><span></span><br><span>By incorporating partial initializers, it would be possible to guarantee that a `let` variable in a protocol is only set once. This is because an init implemented in a protocol extension could delegate to a partial initializers required by the protocol, and because they are only partial initializers, they need not set the instance variables already set in the initializer; it would be up to a conforming type to ensure this is the caee. A confirming type would define the partial initializer to set everything not already set in the protocol extension’s init, and it would be a compiler error to set a variable in the partial initializer that is already set in the extension’s init without overriding the extension’s init. Example code:</span><br><span></span><br><span>protocol P {</span><br><span> &nbsp;&nbsp;&nbsp;var x: Int { let } // or { get set(init) }, or whatever</span><br><span></span><br><span> &nbsp;&nbsp;&nbsp;partialinit initializeRest()</span><br><span> &nbsp;&nbsp;&nbsp;init()</span><br><span>}</span><br><span></span><br><span>extension P {</span><br><span> &nbsp;&nbsp;&nbsp;init() {</span><br><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;initializeRest()</span><br><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.x = 1</span><br><span> &nbsp;&nbsp;&nbsp;}</span><br><span>}</span><br><span></span><br><span>struct S: P {</span><br><span> &nbsp;&nbsp;&nbsp;let x: Int</span><br><span> &nbsp;&nbsp;&nbsp;var y: String</span><br><span></span><br><span> &nbsp;&nbsp;&nbsp;// It would be a compiler error to set x here without also redefining init()</span><br><span> &nbsp;&nbsp;&nbsp;partialinit initializeRest() {</span><br><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.y = “P has no knowledge of me”</span><br><span> &nbsp;&nbsp;&nbsp;}</span><br><span></span><br><span> &nbsp;&nbsp;&nbsp;// Can use default init provided by P</span><br><span>}</span><br><span></span><br><blockquote type="cite"><span>On Jun 23, 2017, at 8:12 PM, Karl Wagner &lt;<a href="mailto:razielim@gmail.com">razielim@gmail.com</a>&gt; wrote:</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>What you want is some way to guarantee value semantics when writing generic code.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>It’s a known hole, and admittedly quite a big one. I hope that there will be time for core language improvements like this in Swift 5. Be sure to raise the issue again once planning for that starts!</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>- Karl</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><blockquote type="cite"><span>On 23. Jun 2017, at 23:43, Robert Bennett via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Hello Swift Evolution,</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>I’m bumping into an annoying problem with protocols. In a class or struct it is common to have a `let` instance variable and assign it in `init`. Unfortunately there is no way to translate this into a protocol with init in an extension. If attempting to set the variable in init in an extension, it must be of type { get set }, which means it cannot be a `let` constant in the conforming type. AFAIK there is no way around this — if you want to set an instance variable in an initializer in a protocol extension, it must be marked as { get set }. The alternative is to write the initializer separately for each adopting type, but this violates DRY.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Hence, I am proposing a third option to go along with `get` and `set` in a protocol. This would indicate that the variable can be a constant, but is settable in an initializer. In this case, the conforming type *must* use `let` to declare the variable.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Option 1: the keyword `let`. If present, it would need to be the only thing in the curly brackets because it simultaneously implies `get` and not `set`.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>protocol P {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;var x: Int { let }</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;init(_ x: Int)</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;func modifyX()</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>extension P {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;init(_ x: Int) {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.x = x // This is ok; would not be ok if x were marked { get }</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;func modifyX() {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.x += 1 // Not allowed</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>struct S: P {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;let x: Int // This is ok; would not be ok if x were marked { get set }</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Option 2: `set(init)`. Can (and often will) coexist with `get`.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>protocol P {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;var x: Int { get set(init) }</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;init(_ x: Int)</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;func modifyX()</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>extension P {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;init(_ x: Int) {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.x = x // This is ok; would not be ok if x were marked { get }</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;func modifyX() {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.x += 1 // Not allowed</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>struct S: P {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;let x: Int // This is ok; would not be ok if x were marked { get set }</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>I’d like to hear all of your thoughts on this.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Best,</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Robert</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>_______________________________________________</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>swift-evolution mailing list</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></blockquote></blockquote><blockquote type="cite"><span></span><br></blockquote><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>