<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">I like the alternative, which makes it clear, at the call site, that the initializer is failable:<div class=""><blockquote type="cite" class=""><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.225; font-size: 1.75em; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><span style="font-size: 16px; font-weight: normal;" class="">An alternative is to change the falliable initiliser to have the optional symbol required at the call-site:</span></h2><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal;" class="">MyModel?()</pre></div></blockquote><div style="box-sizing: border-box; margin-top: 0px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255); margin-bottom: 0px !important;" class=""><br class=""></div><div style="box-sizing: border-box; margin-top: 0px; background-color: rgb(255, 255, 255); margin-bottom: 0px !important;" class="">Here is a rationale: imagine you have a type with a failable initializer AND a function that takes an optional value of this type, with default nil:</div><div style="box-sizing: border-box; margin-top: 0px; background-color: rgb(255, 255, 255); margin-bottom: 0px !important;" class=""><br class=""></div><div style="box-sizing: border-box; margin-top: 0px; background-color: rgb(255, 255, 255); margin-bottom: 0px !important;" class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);" class="">protocol<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> P { }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">struct</span> Value {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span>(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span> array:[<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">P</span>?]) { … }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span>?(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span> nsarray: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">NSArray</span>) { … }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> function(value: <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Value</span>? = <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">nil</span>) { … }</div><div class=""><br class=""></div></div><div style="box-sizing: border-box; margin-top: 0px; background-color: rgb(255, 255, 255); margin-bottom: 0px !important;" class="">The problem is that when the failable initializer fails, the function may not behave as expected:</div><div style="box-sizing: border-box; margin-top: 0px; background-color: rgb(255, 255, 255); margin-bottom: 0px !important;" class=""><br class=""></div><div style="box-sizing: border-box; margin-top: 0px; background-color: rgb(255, 255, 255); margin-bottom: 0px !important;" class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> array: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">NSArray</span> = …</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #31595d" class="">function</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Value</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">array</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">)) </span>// May not do what is expected</div></div><div class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><br class=""></span></div><div class="">With the proposed alternative, the Swift compiler would force the code to read:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="color: rgb(187, 44, 162);" class="">let</span> array: <span style="color: rgb(112, 61, 170);" class="">NSArray</span> = …</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="color: rgb(49, 89, 93);" class="">function</span><span style="color: rgb(0, 0, 0);" class="">(</span><span style="color: rgb(79, 129, 135);" class="">Value?</span><span style="color: rgb(0, 0, 0);" class="">(</span><span style="color: rgb(79, 129, 135);" class="">array</span><span style="color: rgb(0, 0, 0);" class="">)) </span>// Now this is clearly bad. We need a value.</div></div></div></div><div><div class=""><div class=""><br class=""></div><div class="">And the user is more likely to turn it into the correct code:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> array: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">NSArray</span> = …</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">guard</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> value = <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Value</span>(<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">array</span>) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">else</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span>// process problem</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(61, 29, 129);" class="">}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(49, 89, 93);" class="">function<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(value)</span></div></div><div class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><br class=""></span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><br class=""></span></div><div class="">With the current state of Swift, how could the code above be fixed? By "fixed" I mean that it’s impossible for the user to trigger the default function value without knowing it:</div><div class=""><br class=""></div><div class="">1. Don’t use nil as a sentinel for the default value, and split the function in two variants:</div><div class=""><br class=""></div><div class=""><div style="background-color: rgb(255, 255, 255); margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);" class="">protocol<span style="color: rgb(0, 0, 0);" class=""> P { }</span></div><div style="background-color: rgb(255, 255, 255); margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="color: rgb(187, 44, 162);" class="">struct</span> Value {</div><div style="background-color: rgb(255, 255, 255); margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color: rgb(187, 44, 162);" class="">init</span>(<span style="color: rgb(187, 44, 162);" class="">_</span> array:[<span style="color: rgb(79, 129, 135);" class="">P</span>?]) { … }</div><div style="background-color: rgb(255, 255, 255); margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color: rgb(187, 44, 162);" class="">init</span>?(<span style="color: rgb(187, 44, 162);" class="">_</span> nsarray: <span style="color: rgb(112, 61, 170);" class="">NSArray</span>) { … }</div><div style="background-color: rgb(255, 255, 255); margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div><div class=""><div style="background-color: rgb(255, 255, 255); margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="color: rgb(187, 44, 162);" class="">func</span> function() { … }</div></div><div style="background-color: rgb(255, 255, 255); margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="color: rgb(187, 44, 162);" class="">func</span> function(value: <span style="color: rgb(79, 129, 135);" class="">Value</span>) { … }</div></div><div class=""><div style="background-color: rgb(255, 255, 255); margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal; color: rgb(79, 129, 135);" class=""><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="color: rgb(49, 89, 93);" class=""><br class=""></span></div><div style="color: rgb(0, 0, 0); margin: 0px; line-height: normal;" class=""><span style="color: rgb(187, 44, 162);" class="">let</span> array: <span style="color: rgb(112, 61, 170);" class="">NSArray</span> = …</div><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="color: rgb(49, 89, 93);" class="">function</span><span style="color: rgb(0, 0, 0);" class="">(</span><span style="color: rgb(79, 129, 135);" class="">Value</span><span style="color: rgb(0, 0, 0);" class="">(</span><span style="color: rgb(79, 129, 135);" class="">array</span><span style="color: rgb(0, 0, 0);" class="">)) </span>// OK: does not compile</div><div class=""><br class=""></div></div></div><div class="">It works, BUT it may lead to an API explosion.</div><div class=""><br class=""></div><div class="">2. Don’t use nil as a sentinel for the default value, and use a special sentinel value instead:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);" class="">protocol<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> P { }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">struct</span> Value {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">static</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span> DefaultValue: <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Value</span> = ...</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span>(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span> array:[<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">P</span>?]) { }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span>?(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span> nsarray: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">NSArray</span>) { }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> function(value: <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Value</span> = <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Value</span>.DefaultValue) { }</div></div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="color: rgb(187, 44, 162);" class="">let</span> array: <span style="color: rgb(112, 61, 170);" class="">NSArray</span> = …</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="color: rgb(49, 89, 93);" class="">function</span><span style="color: rgb(0, 0, 0);" class="">(</span><span style="color: rgb(79, 129, 135);" class="">Value</span><span style="color: rgb(0, 0, 0);" class="">(</span><span style="color: rgb(79, 129, 135);" class="">array</span><span style="color: rgb(0, 0, 0);" class="">)) </span>// OK: does not compile</div></div><div class=""><br class=""></div></div></div><div class=""><div class="">It works, BUT not all types can easily lock a value for such a purpose. Plus it’s a very uncommon pattern.</div><div class=""><br class=""></div><div class="">I don’t see any other way to fix the problem.</div><div class=""><br class=""></div><div class="">So I would quite welcome the alternative proposed by James Campbell.</div><div class=""><br class=""></div><div class="">Gwendal</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""></div></div><blockquote type="cite" class=""><div style="background-color: rgb(255, 255, 255);" class=""></div><div class="">Le 7 mars 2016 à 16:40, James Campbell via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> a écrit :</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">This is my draft proposal.<div class=""><br class=""></div><div class=""><a href="https://github.com/jcampbell05/swift-evolution/blob/master/proposals/0045-remove-falliable-initilizer.md" class="">https://github.com/jcampbell05/swift-evolution/blob/master/proposals/0045-remove-falliable-initilizer.md</a><br class=""></div><div class=""><br class=""></div><div class="">Let me know your thoughts.</div></div></div></blockquote><br class=""></div><br class=""></div></body></html>