<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">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: <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160104/006176.html" class="">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160104/006176.html</a></div><div class=""><br class=""></div><div class="">Partial initializers is the second in a series of three proposals describing general features that can work together to form a complete solution.</div><div class=""><br class=""></div><div class=""><div class="">The proposal drafts can be found at the following links:</div><div class=""><br class=""></div><div class="">* <b class="">Parameter forwarding:</b> <a href="https://github.com/anandabits/swift-evolution/blob/parameter-forwarding/proposals/NNNN-parameter-forwarding.md" class="">https://github.com/anandabits/swift-evolution/blob/parameter-forwarding/proposals/NNNN-parameter-forwarding.md</a></div><div class="">* <b class="">Partial initializers:</b> <a href="https://github.com/anandabits/swift-evolution/blob/partial-initializers/proposals/NNNN-partial-initializers.md" class="">https://github.com/anandabits/swift-evolution/blob/partial-initializers/proposals/NNNN-partial-initializers.md</a></div><div class="">* <b class="">Property lists:</b> <a href="https://github.com/anandabits/swift-evolution/blob/property-lists/proposals/NNNN-property-lists.md" class="">https://github.com/anandabits/swift-evolution/blob/property-lists/proposals/NNNN-property-lists.md</a></div></div><div class=""><br class=""></div><div class="">Matthew</div><div class=""><h1 id="partialinitializers" style="font-size: 37px; line-height: 42px; margin-top: 42px; margin-bottom: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Partial Initializers</h1><ul style="margin-top: 21px; margin-bottom: 21px; padding-left: 1.5em; color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; font-size: 15px;" class=""><li style="font-size: 17px;" class="">Proposal: <a href="https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-partial-initializers.md" style="color: rgb(13, 110, 161); text-decoration: none; transition: color 0.2s ease-in-out; -webkit-transition: color 0.2s ease-in-out;" class="">SE-NNNN</a></li><li style="font-size: 17px;" class="">Author(s): <a href="https://github.com/anandabits" style="color: rgb(13, 110, 161); text-decoration: none; transition: color 0.2s ease-in-out; -webkit-transition: color 0.2s ease-in-out;" class="">Matthew Johnson</a></li><li style="font-size: 17px;" class="">Status: <strong style="line-height: 1;" class="">Awaiting review</strong></li><li style="font-size: 17px;" class="">Review manager: TBD</li></ul><h2 id="introduction" style="color: rgb(17, 17, 17); font-size: 27px; line-height: 42px; margin-top: 42px; margin-bottom: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Introduction</h2><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">This proposal introduces partial initializers. They perform part, but not all, of phase 1 initialization for a type. Partial initializers can only be called by designated initializers of the same type or other partial initializers of the same type.</p><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">Swift-evolution thread: <a href="https://lists.swift.org/pipermail/swift-evolution" style="color: rgb(13, 110, 161); text-decoration: none; transition: color 0.2s ease-in-out; -webkit-transition: color 0.2s ease-in-out;" class="">Proposal Draft: Partial Initializers</a></p><h2 id="motivation" style="color: rgb(17, 17, 17); font-size: 27px; line-height: 42px; margin-top: 42px; margin-bottom: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Motivation</h2><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">Partial initializers will make it much easier to factor out common initialization logic than it is today.</p><h3 id="memberwiseinitialization" style="color: rgb(17, 17, 17); margin: 21px 0px; font-size: 20px; line-height: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Memberwise initialization</h3><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">Partial initializers are a general feature that can work together with <a href="https://github.com/anandabits/swift-evolution/edit/parameter-forwarding/proposals/NNNN-parameter-forwarding.md" style="color: rgb(13, 110, 161); text-decoration: none; transition: color 0.2s ease-in-out; -webkit-transition: color 0.2s ease-in-out;" class="">Parameter Forwarding</a> and <a href="https://github.com/anandabits/swift-evolution/blob/property-lists/proposals/NNNN-property-lists.md" style="color: rgb(13, 110, 161); text-decoration: none; transition: color 0.2s ease-in-out; -webkit-transition: color 0.2s ease-in-out;" class="">Property Lists</a> to enable extremely flexible memberwise initialization. </p><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">The combination of partial initializers and parameter forwarding is sufficiently powerfule to replace the explicit memberwise initializers of the <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0018-flexible-memberwise-initialization.md" style="color: rgb(13, 110, 161); text-decoration: none; transition: color 0.2s ease-in-out; -webkit-transition: color 0.2s ease-in-out;" class="">Flexible Memberwise Initialization</a> proposal by simply adding a three implicit partial initializers.</p><h3 id="extensionswithstoredproperties" style="color: rgb(17, 17, 17); margin: 21px 0px; font-size: 20px; line-height: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Extensions with stored properties</h3><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">Partial initialization is an enabling feature for stored properties in class extensions. Extension with stored properties would be required to have a designated initializer. That extension initializer would effectively be treated as a partial initializer by designated initializers of the class. </p><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">John McCall <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004479.html" style="color: rgb(13, 110, 161); text-decoration: none; transition: color 0.2s ease-in-out; -webkit-transition: color 0.2s ease-in-out;" class="">briefly described</a> how this might work in the mailing list thread discussing extensions with stored properties. </p><h2 id="proposedsolution" style="color: rgb(17, 17, 17); font-size: 27px; line-height: 42px; margin-top: 42px; margin-bottom: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Proposed solution</h2><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">The proposed solution is to introduce a <code style="line-height: 1;" class="">partial</code> declaration modifier for initializers. </p><ol style="margin-top: 21px; margin-bottom: 21px; padding-left: 1.5em; color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; font-size: 15px;" class=""><li style="font-size: 17px;" class=""><div style="word-wrap: break-word; margin: 0px; line-height: 1.3125em;" class="">When this declaration modifier is present the entire body of the initializer must comply with phase 1 initialization. It is possible for a partial initializer to initialize all stored properties but it is not possible for a partial initializer to call a <code style="line-height: 1;" class="">super</code> initializer.</div></li><li style="font-size: 17px;" class=""><div style="word-wrap: break-word; margin: 0px; line-height: 1.3125em;" class="">Partial initializers can only be called during phase 1 of initialization by another partial initalizer of the same type, by a designated initializer of the same type, or by another struct initializer of the same type.</div></li><li style="font-size: 17px;" class=""><div style="word-wrap: break-word; margin: 0px; line-height: 1.3125em;" class="">The compiler keeps track of the properties initialized by a call to a partial initializer and uses that knowledge when enforcing initialization rules in phase 1 in the calling initializer.</div></li><li style="font-size: 17px;" class=""><div style="word-wrap: break-word; margin: 0px; line-height: 1.3125em;" class="">Partial initializers receive an identifier, which avoids the need to rely on overloading to differentiate between partial initializers.</div></li><li style="font-size: 17px;" class=""><div style="word-wrap: break-word; margin: 0px; line-height: 1.3125em;" class="">Struct partial initializers are allowed to include an access control modifier specifying their visibility. They can be called in any initializer of the same type where they are visible.</div></li><li style="font-size: 17px;" class=""><div style="word-wrap: break-word; margin: 0px; line-height: 1.3125em;" class="">Class partial initializers are always private. This is because they can only be declared in the main body of a class and can only be called by a designated initializer of the same type.</div></li><li style="font-size: 17px;" class=""><div style="word-wrap: break-word; margin: 0px; line-height: 1.3125em;" class="">There is no restriction on the order in which the partial initializers are called aside from the rule that the can only be called during phase 1 of initialization and the rule that a <code style="line-height: 1;" class="">let</code> property must be initialized once and only once during phase 1.</div></li></ol><h3 id="basicexample" style="color: rgb(17, 17, 17); margin: 21px 0px; font-size: 20px; line-height: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Basic example</h3><pre style="margin-top: 21px; margin-bottom: 21px; tab-size: 4; color: rgb(17, 17, 17); font-size: 15px;" class=""><code class="swift hljs" style="line-height: inherit; display: block; padding: 0.5em; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); height: auto; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-class"><span class="hljs-keyword" style="font-weight: bold;">struct</span> <span class="hljs-title" style="color: rgb(68, 85, 136); font-weight: bold;">S</span> </span>{
<span class="hljs-keyword" style="font-weight: bold;">let</span> a, b, <span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span>, d: <span class="hljs-type">Int</span>
partial <span class="hljs-keyword" style="font-weight: bold;">init</span> bAndC(i: <span class="hljs-type">Int</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">10</span>) {
b = <span class="hljs-number" style="color: rgb(0, 153, 153);">10</span>
<span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">20</span>
}
<span class="hljs-keyword" style="font-weight: bold;">init</span>(i: <span class="hljs-type">Int</span>) {
a = i * <span class="hljs-number" style="color: rgb(0, 153, 153);">2</span>
d = i * <span class="hljs-number" style="color: rgb(0, 153, 153);">4</span>
bAndC.<span class="hljs-keyword" style="font-weight: bold;">init</span>()
}
}</code></pre><h3 id="callingmultiplepartialinitializers" style="color: rgb(17, 17, 17); margin: 21px 0px; font-size: 20px; line-height: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Calling multiple partial initializers</h3><pre style="margin-top: 21px; margin-bottom: 21px; tab-size: 4; color: rgb(17, 17, 17); font-size: 15px;" class=""><code class="swift hljs" style="line-height: inherit; display: block; padding: 0.5em; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); height: auto; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-class"><span class="hljs-keyword" style="font-weight: bold;">struct</span> <span class="hljs-title" style="color: rgb(68, 85, 136); font-weight: bold;">S</span> </span>{
<span class="hljs-keyword" style="font-weight: bold;">let</span> a, b, <span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span>, d: <span class="hljs-type">Int</span>
partial <span class="hljs-keyword" style="font-weight: bold;">init</span> bAndC() {
b = <span class="hljs-number" style="color: rgb(0, 153, 153);">10</span>
<span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">20</span>
}
partial <span class="hljs-keyword" style="font-weight: bold;">init</span> configureD(i: <span class="hljs-type">Int</span>) {
d = i * <span class="hljs-number" style="color: rgb(0, 153, 153);">4</span>
}
<span class="hljs-keyword" style="font-weight: bold;">init</span>(i: <span class="hljs-type">Int</span>) {
configureD.<span class="hljs-keyword" style="font-weight: bold;">init</span>(i)
a = i * <span class="hljs-number" style="color: rgb(0, 153, 153);">2</span>
bAndC.<span class="hljs-keyword" style="font-weight: bold;">init</span>()
}
}</code></pre><h3 id="onepartialinitcallinganother" style="color: rgb(17, 17, 17); margin: 21px 0px; font-size: 20px; line-height: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">One partial init calling another</h3><pre style="margin-top: 21px; margin-bottom: 21px; tab-size: 4; color: rgb(17, 17, 17); font-size: 15px;" class=""><code class="swift hljs" style="line-height: inherit; display: block; padding: 0.5em; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); height: auto; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-class"><span class="hljs-keyword" style="font-weight: bold;">struct</span> <span class="hljs-title" style="color: rgb(68, 85, 136); font-weight: bold;">S</span> </span>{
<span class="hljs-keyword" style="font-weight: bold;">let</span> a, b, <span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span>, d: <span class="hljs-type">Int</span>
partial <span class="hljs-keyword" style="font-weight: bold;">init</span> bAndC() {
b = <span class="hljs-number" style="color: rgb(0, 153, 153);">10</span>
<span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">20</span>
}
partial <span class="hljs-keyword" style="font-weight: bold;">init</span> bcAndD(i: <span class="hljs-type">Int</span>) {
d = i * <span class="hljs-number" style="color: rgb(0, 153, 153);">4</span>
bAndC.<span class="hljs-keyword" style="font-weight: bold;">init</span>()
}
<span class="hljs-keyword" style="font-weight: bold;">init</span>(i: <span class="hljs-type">Int</span>) {
a = i * <span class="hljs-number" style="color: rgb(0, 153, 153);">2</span>
bcAndD.<span class="hljs-keyword" style="font-weight: bold;">init</span>(i)
}
}</code></pre><h3 id="syntacticsugarforforwarding" style="color: rgb(17, 17, 17); margin: 21px 0px; font-size: 20px; line-height: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Syntactic sugar for forwarding</h3><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">It will be a common use case to factor out some common initialization logic using a partial initializer. Often the parameters for the partial initializer will simply be forwarded. </p><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">Syntactic sugar is provided to streamline this use case. It matches the placeholder syntax of the <a href="https://github.com/anandabits/swift-evolution/blob/parameter-forwarding/proposals/NNNN-parameter-forwarding.md" style="color: rgb(13, 110, 161); text-decoration: none; transition: color 0.2s ease-in-out; -webkit-transition: color 0.2s ease-in-out;" class="">parameter forwarding proposal</a>, with the placeholder identifier matching the name of a partial initializer. The implementation of forwarding matches the implementation of the parameter forwarding proposal.</p><h4 id="basicforwardingsugarexample" style="color: rgb(17, 17, 17); font-size: 20px; line-height: 21px; margin-top: 21px; margin-bottom: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Basic forwarding sugar example</h4><pre style="margin-top: 21px; margin-bottom: 21px; tab-size: 4; color: rgb(17, 17, 17); font-size: 15px;" class=""><code class="swift hljs" style="line-height: inherit; display: block; padding: 0.5em; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); height: auto; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-class"><span class="hljs-keyword" style="font-weight: bold;">struct</span> <span class="hljs-title" style="color: rgb(68, 85, 136); font-weight: bold;">S</span> </span>{
<span class="hljs-keyword" style="font-weight: bold;">let</span> a, b, <span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span>, d: <span class="hljs-type">Int</span>
partial <span class="hljs-keyword" style="font-weight: bold;">init</span> bAndC(b: <span class="hljs-type">Int</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">10</span>, cLabel <span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span>: <span class="hljs-type">Int</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">20</span>) {
b = b
<span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span> = <span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span>
}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// user writes</span>
<span class="hljs-keyword" style="font-weight: bold;">init</span>(i: <span class="hljs-type">Int</span>, ...bAndC) {
a = i * <span class="hljs-number" style="color: rgb(0, 153, 153);">2</span>
d = i * <span class="hljs-number" style="color: rgb(0, 153, 153);">4</span>
}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// compiler synthesizes</span>
<span class="hljs-keyword" style="font-weight: bold;">init</span>(i: <span class="hljs-type">Int</span>, b: <span class="hljs-type">Int</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">10</span>, cLabel: <span class="hljs-type">Int</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">20</span>) {
bAndC.<span class="hljs-keyword" style="font-weight: bold;">init</span>(b: b, cLabel: cLabel)
a = i * <span class="hljs-number" style="color: rgb(0, 153, 153);">2</span>
d = i * <span class="hljs-number" style="color: rgb(0, 153, 153);">4</span>
}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// equivalent to writing the following under the parameter forwarding proposal:</span>
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// <span class="hljs-doctag">NOTE:</span> the placeholder identifier is changed to `bAndCParams` here to avoid</span>
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// conflict with the name of the partial initializer itself</span>
<span class="hljs-keyword" style="font-weight: bold;">init</span>(i: <span class="hljs-type">Int</span>, ...bAndCParams) {
bAndC.<span class="hljs-keyword" style="font-weight: bold;">init</span>(...bAndCParams)
a = i * <span class="hljs-number" style="color: rgb(0, 153, 153);">2</span>
d = i * <span class="hljs-number" style="color: rgb(0, 153, 153);">4</span>
}
}</code></pre><h4 id="forwardingtomorethanonepartialinitializer" style="color: rgb(17, 17, 17); font-size: 20px; line-height: 21px; margin-top: 21px; margin-bottom: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Forwarding to more than one partial initializer</h4><pre style="margin-top: 21px; margin-bottom: 21px; tab-size: 4; color: rgb(17, 17, 17); font-size: 15px;" class=""><code class="swift hljs" style="line-height: inherit; display: block; padding: 0.5em; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); height: auto; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-class"><span class="hljs-keyword" style="font-weight: bold;">struct</span> <span class="hljs-title" style="color: rgb(68, 85, 136); font-weight: bold;">S</span> </span>{
<span class="hljs-keyword" style="font-weight: bold;">let</span> a, b, <span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span>, d: <span class="hljs-type">Int</span>
partial <span class="hljs-keyword" style="font-weight: bold;">init</span> bAndC(b: <span class="hljs-type">Int</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">10</span>, cLabel <span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span>: <span class="hljs-type">Int</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">20</span>) {
b = b
<span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span> = <span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span>
}
partial <span class="hljs-keyword" style="font-weight: bold;">init</span> aAndD(i: <span class="hljs-type">Int</span>) {
a = i * <span class="hljs-number" style="color: rgb(0, 153, 153);">10</span>
d = i * <span class="hljs-number" style="color: rgb(0, 153, 153);">100</span>
}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// user writes</span>
<span class="hljs-keyword" style="font-weight: bold;">init</span>(...aAndD, ...bAndC) {}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// compiler synthesizes</span>
<span class="hljs-keyword" style="font-weight: bold;">init</span>(i: <span class="hljs-type">Int</span>, b: <span class="hljs-type">Int</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">10</span>, cLabel: <span class="hljs-type">Int</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">20</span>) {
aAndD.<span class="hljs-keyword" style="font-weight: bold;">init</span>(i: <span class="hljs-type">Int</span>)
bAndC.<span class="hljs-keyword" style="font-weight: bold;">init</span>(b: b, cLabel: cLabel)
}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// equivalent to writing the following under the parameter forwarding proposal:</span>
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// <span class="hljs-doctag">NOTE:</span> the placeholder identifier is changed to `bAndCParams` here to avoid</span>
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// conflict with the name of the partial initializer itself</span>
<span class="hljs-keyword" style="font-weight: bold;">init</span>(...aAndDParams, ...bAndCParams) {
aAndD.<span class="hljs-keyword" style="font-weight: bold;">init</span>(...aAndDParams)
bAndC.<span class="hljs-keyword" style="font-weight: bold;">init</span>(...bAndCParams)
}
}</code></pre><h4 id="onepartialinitizerforwardingtoanother" style="color: rgb(17, 17, 17); font-size: 20px; line-height: 21px; margin-top: 21px; margin-bottom: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">One partial initizer forwarding to another</h4><pre style="margin-top: 21px; margin-bottom: 21px; tab-size: 4; color: rgb(17, 17, 17); font-size: 15px;" class=""><code class="swift hljs" style="line-height: inherit; display: block; padding: 0.5em; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); height: auto; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-class"><span class="hljs-keyword" style="font-weight: bold;">struct</span> <span class="hljs-title" style="color: rgb(68, 85, 136); font-weight: bold;">S</span> </span>{
<span class="hljs-keyword" style="font-weight: bold;">let</span> a, b, <span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span>, d: <span class="hljs-type">Int</span>
partial <span class="hljs-keyword" style="font-weight: bold;">init</span> bAndC(b: <span class="hljs-type">Int</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">10</span>, cLabel <span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span>: <span class="hljs-type">Int</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">20</span>) {
b = b
<span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span> = <span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span>
}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// user writes</span>
partial <span class="hljs-keyword" style="font-weight: bold;">init</span> abAndC(...bAndC) {
a = <span class="hljs-number" style="color: rgb(0, 153, 153);">42</span>
}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// compiler synthesizes</span>
partial <span class="hljs-keyword" style="font-weight: bold;">init</span> abAndC(b: <span class="hljs-type">Int</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">10</span>, cLabel <span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span>: <span class="hljs-type">Int</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">20</span>) {
bAndC.<span class="hljs-keyword" style="font-weight: bold;">init</span>(b: b, <span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span>: <span class="hljs-built_in" style="color: rgb(0, 134, 179);">c</span>)
a = <span class="hljs-number" style="color: rgb(0, 153, 153);">42</span>
}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// equivalent to writing the following under the parameter forwarding proposal:</span>
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// <span class="hljs-doctag">NOTE:</span> the placeholder identifier is changed to `bAndCParams` here to avoid</span>
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// conflict with the name of the partial initializer itself</span>
partial <span class="hljs-keyword" style="font-weight: bold;">init</span> abAndC(i: <span class="hljs-type">Int</span>, ...bAndCParams) {
bAndC.<span class="hljs-keyword" style="font-weight: bold;">init</span>(...bAndCParams)
a = <span class="hljs-number" style="color: rgb(0, 153, 153);">42</span>
}
}</code></pre><h4 id="forwardingtosuper" style="color: rgb(17, 17, 17); font-size: 20px; line-height: 21px; margin-top: 21px; margin-bottom: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Forwarding to super</h4><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">If super contains a single designated initializer subclasses can use the same syntax to forward parameters to the super initializer. The call to super is added at the end of the initializer body. This means that if phase 2 initialization logic is necessary it will not be possible to use the syntactic sugar.</p><pre style="margin-top: 21px; margin-bottom: 21px; tab-size: 4; color: rgb(17, 17, 17); font-size: 15px;" class=""><code class="swift hljs" style="line-height: inherit; display: block; padding: 0.5em; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); height: auto; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-class"><span class="hljs-keyword" style="font-weight: bold;">class</span> <span class="hljs-title" style="color: rgb(68, 85, 136); font-weight: bold;">Base</span> </span>{
<span class="hljs-keyword" style="font-weight: bold;">init</span>(i: <span class="hljs-type">Int</span>, s: <span class="hljs-type">String</span>, f: <span class="hljs-type">Float</span>) {}
}
<span class="hljs-class"><span class="hljs-keyword" style="font-weight: bold;">class</span> <span class="hljs-title" style="color: rgb(68, 85, 136); font-weight: bold;">Derived</span>: <span class="hljs-title" style="color: rgb(68, 85, 136); font-weight: bold;">Base</span> </span>{
<span class="hljs-keyword" style="font-weight: bold;">let</span> d: <span class="hljs-type">Double</span>
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// user writes</span>
<span class="hljs-keyword" style="font-weight: bold;">init</span>(...<span class="hljs-keyword" style="font-weight: bold;">super</span>) {
d = <span class="hljs-number" style="color: rgb(0, 153, 153);">42</span>
}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// compiler synthesizes</span>
<span class="hljs-keyword" style="font-weight: bold;">init</span>(i: <span class="hljs-type">Int</span>, s: <span class="hljs-type">String</span>, f: <span class="hljs-type">Float</span>) {
d = <span class="hljs-number" style="color: rgb(0, 153, 153);">42</span>
<span class="hljs-keyword" style="font-weight: bold;">super</span>.<span class="hljs-keyword" style="font-weight: bold;">init</span>(i: i, s: s, f: f)
}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// equivalent to writing the following under the parameter forwarding proposal:</span>
<span class="hljs-keyword" style="font-weight: bold;">init</span>(...superParams) {
d = <span class="hljs-number" style="color: rgb(0, 153, 153);">42</span>
<span class="hljs-keyword" style="font-weight: bold;">super</span>.<span class="hljs-keyword" style="font-weight: bold;">init</span>(...superParams)
}
}</code></pre><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">If super contains more than one initializer</p><pre style="margin-top: 21px; margin-bottom: 21px; tab-size: 4; color: rgb(17, 17, 17); font-size: 15px;" class=""><code class="swift hljs" style="line-height: inherit; display: block; padding: 0.5em; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); height: auto; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-class"><span class="hljs-keyword" style="font-weight: bold;">struct</span> <span class="hljs-title" style="color: rgb(68, 85, 136); font-weight: bold;">S</span> </span>{
<span class="hljs-keyword" style="font-weight: bold;">let</span> i: <span class="hljs-type">Int</span>, s: <span class="hljs-type">String</span>, f: <span class="hljs-type">Float</span>
}
<span class="hljs-class"><span class="hljs-keyword" style="font-weight: bold;">class</span> <span class="hljs-title" style="color: rgb(68, 85, 136); font-weight: bold;">Base</span> </span>{
<span class="hljs-keyword" style="font-weight: bold;">init</span>(s: <span class="hljs-type">S</span>) {}
<span class="hljs-keyword" style="font-weight: bold;">init</span>(i: <span class="hljs-type">Int</span>, s: <span class="hljs-type">String</span>, f: <span class="hljs-type">Float</span>) {}
}
<span class="hljs-class"><span class="hljs-keyword" style="font-weight: bold;">class</span> <span class="hljs-title" style="color: rgb(68, 85, 136); font-weight: bold;">Derived</span>: <span class="hljs-title" style="color: rgb(68, 85, 136); font-weight: bold;">Base</span> </span>{
<span class="hljs-keyword" style="font-weight: bold;">let</span> d: <span class="hljs-type">Double</span> = <span class="hljs-number" style="color: rgb(0, 153, 153);">42</span>
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// error: ambiguous forward to super</span>
<span class="hljs-keyword" style="font-weight: bold;">init</span>(...<span class="hljs-keyword" style="font-weight: bold;">super</span>) {}
}</code></pre><h3 id="implicitpartialinitializers" style="color: rgb(17, 17, 17); margin: 21px 0px; font-size: 20px; line-height: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Implicit partial initializers</h3><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">Three implicit paritial initializers exist. They match the behavior of <code style="line-height: 1;" class="">public</code>, <code style="line-height: 1;" class="">internal</code>, and <code style="line-height: 1;" class="">private</code> memberwise intializers using the automatic property eligibility model described in the <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0018-flexible-memberwise-initialization.md" style="color: rgb(13, 110, 161); text-decoration: none; transition: color 0.2s ease-in-out; -webkit-transition: color 0.2s ease-in-out;" class="">Flexible Memberwise Initialization</a> proposal, thus making that proposal obsolete if this proposal is accepted. The <code style="line-height: 1;" class="">private</code> and <code style="line-height: 1;" class="">internal</code> implicit partial initializers also match the behavior of the implicit memberwise initializer if one exists for the type.</p><pre style="margin-top: 21px; margin-bottom: 21px; tab-size: 4; color: rgb(17, 17, 17); font-size: 15px;" class=""><code class="swift hljs" style="line-height: inherit; display: block; padding: 0.5em; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); height: auto; background-position: initial initial; background-repeat: initial initial;"> <span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// flexibile memberwise initialization proposal:</span>
<span class="hljs-keyword" style="font-weight: bold;">public</span> memberwise <span class="hljs-keyword" style="font-weight: bold;">init</span>(...) {
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// init all private an internal props</span>
}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// corresponding syntax using implicit partial init and forwarding:</span>
<span class="hljs-keyword" style="font-weight: bold;">public</span> <span class="hljs-keyword" style="font-weight: bold;">init</span>(...publicMemberwise) {
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// init all private an internal props</span>
}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// flexibile memberwise initialization proposal:</span>
memberwise <span class="hljs-keyword" style="font-weight: bold;">init</span>(...) {
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// init all private props</span>
}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// corresponding syntax using implicit partial init and forwarding:</span>
<span class="hljs-keyword" style="font-weight: bold;">init</span>(...internalMemberwise) {
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// init all private props</span>
}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// flexibile memberwise initialization proposal:</span>
<span class="hljs-keyword" style="font-weight: bold;">private</span> memberwise <span class="hljs-keyword" style="font-weight: bold;">init</span>(...) {}
<span class="hljs-comment" style="color: rgb(153, 153, 136); font-style: italic;">// corresponding syntax using implicit partial init and forwarding:</span>
<span class="hljs-keyword" style="font-weight: bold;">private</span> <span class="hljs-keyword" style="font-weight: bold;">init</span>(...privateMemberwise) {}</code></pre><h2 id="detaileddesign" style="color: rgb(17, 17, 17); font-size: 27px; line-height: 42px; margin-top: 42px; margin-bottom: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Detailed design</h2><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">TODO but should fall out pretty clearly from the proposed solution</p><h2 id="impactonexistingcode" style="color: rgb(17, 17, 17); font-size: 27px; line-height: 42px; margin-top: 42px; margin-bottom: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Impact on existing code</h2><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">This is a strictly additive change. It has no impact on existing code.</p><h2 id="alternativesconsidered" style="color: rgb(17, 17, 17); font-size: 27px; line-height: 42px; margin-top: 42px; margin-bottom: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Alternatives considered</h2><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">I believe the basic structure of partial initialization falls naturally out of the current initialization rules.</p><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">The syntax for declaring and invoking partial initializers is game for bikeshedding.</p><h3 id="memberscomputedtupleproperty" style="color: rgb(17, 17, 17); margin: 21px 0px; font-size: 20px; line-height: 21px; font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;" class="">Members computed tuple property</h3><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">Joe Groff posted the idea of using a <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160104/005619.html" style="color: rgb(13, 110, 161); text-decoration: none; transition: color 0.2s ease-in-out; -webkit-transition: color 0.2s ease-in-out;" class=""><code style="line-height: 1;" class="">members</code> computed tuple property</a> during the review of the <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0018-flexible-memberwise-initialization.md" style="color: rgb(13, 110, 161); text-decoration: none; transition: color 0.2s ease-in-out; -webkit-transition: color 0.2s ease-in-out;" class="">Flexible Memberwise Initialization</a> proposal. The ensuing discussion inspired me to think more deeply about how more general features could support the memberwise initialization use case. That line of thinking eventually led me to create this proposal as well as the <a href="https://github.com/anandabits/swift-evolution/blob/partial-initializers/proposals/https://github.com/anandabits/swift-evolution/blob/property-lists/proposals/NNNN-property-lists.md" style="color: rgb(13, 110, 161); text-decoration: none; transition: color 0.2s ease-in-out; -webkit-transition: color 0.2s ease-in-out;" class="">Property Lists</a> proposal.</p><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">There are a few problems with the <code style="line-height: 1;" class="">members</code> computed tuple approach:</p><ol style="margin-top: 21px; margin-bottom: 21px; padding-left: 1.5em; color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; font-size: 15px;" class=""><li style="font-size: 17px;" class="">It uses a computed property setter to initialize <code style="line-height: 1;" class="">let</code> properties. This is not something you can do in manually written code and just feels wrong. Initialization, especially of <code style="line-height: 1;" class="">let</code> properties, but also the first <code style="line-height: 1;" class="">set</code> of a <code style="line-height: 1;" class="">var</code> property, should happen in an initilizer context. Partial initializers allow for that in a much more elegant fashion than a weird special case property with a setter that is kind of an initializer.</li><li style="font-size: 17px;" class="">The question of how to expose default property values in initializer parameters was never answered.</li><li style="font-size: 17px;" class="">The question of how to provide memberwise initialization for a subset of properties was never answered.</li></ol><div class=""><br class=""></div></div></body></html>