<div dir="ltr">Jean-Daniel, I agree with the first part of your assessment fully, which in my opinion is actually why I think the Kotlin style combined with the Swift style would pull in the best of both worlds and create a complete solution. I do share some of your reservation in the second part of your assessment, which is why I&#39;m a little hesitant on the proposal, but as I&#39;ve described before I think it would help expressiveness.</div><br><div class="gmail_quote"><div dir="ltr">On Sun, Nov 13, 2016 at 11:16 AM Jean-Daniel &lt;<a href="mailto:dev@xenonium.com">dev@xenonium.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">Le 13 nov. 2016 à 03:37, Dennis Lysenko via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; a écrit :</div><br class="m_-6649614470166047773Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div dir="ltr" class="gmail_msg">That&#39;s a good point in Jay&#39;s example and from what I can tell a good way to address it, Haravikk. <div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I&#39;ve done some work in a language that only provides type narrowing for immutable types (that&#39;d be Kotlin as I&#39;ve mentioned before) and whenever I&#39;ve used it it feels like the only thing it&#39;s really been missing is the &quot;if let&quot; construct allowing you to bind and unwrap mutable values, which leads me to think that synergistically, in Swift, this would be fantastic. The main benefit probably is that it would allow code to read much better.</div></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg">IMHO, the Kotlin solution is flaw. The fact that type narrowing does not works for var and that there is no simple way to unwrap optional just force the developer either to introduce local variable, or to use the force unwrap operator.</div><div class="gmail_msg">Moreover, introducing a unwrap syntax (if let) like in swift would just result in having 2 different and inconsistent way to do the same thing.</div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><div dir="ltr" class="gmail_msg"><div class="gmail_msg">I think the &quot;type stack&quot; phrasing in the proposal is throwing some people for a loop making them think it&#39;ll have way more mental overhead than it actually does in practice...really, in practice, I&#39;ve used this either (a) for checking nullity or (b) for checking for a specific subclass. There&#39;s little to no mental overhead in either of those cases, as your &quot;type stack&quot; is simply 2-long (this was an Int? outside of this conditional block, and it&#39;s an Int inside. This was a UIViewController outside of this conditional block, and it&#39;s a UINavigationController inside.)</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">While it may not be a panacea that allows new applications that no one could have thought of, I have no doubt that it would greatly improve the experience of coding in the language by, as you said, allowing more flexibility in expressiveness. Regardless of one&#39;s opinion on the efficacy of this feature as a whole, there *are* frequent situations where this feature leads to substantially better-reading code. The &quot;unwrap&quot; keyword proposed in another thread, critically, solves only <b class="gmail_msg">half</b> of the  problems that this proposal solves (as far as I could tell from reading a few emails in the chain, it left the subclass inference completely untouched). Ability to say &quot;if (controller is SongSelectionViewController) { controller.search(for: &quot;mozart&quot;) }&quot; is mentally freeing and helps me stay in coder zen. </div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">IMO, it would effectively be the cream cheese icing on the top of the carrot cake of Swift&#39;s unwrapping and type inference features. A good tasteful cream cheese icing always improves a carrot cake. </div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">The question then becomes, is it really worth the implementation time? This is something that, presumably, someone from the Swift team would need to be involved in answering. </div></div><br class="gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Fri, Nov 11, 2016 at 10:52 AM Haravikk via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On 10 Nov 2016, at 21:42, Jay Abbott &lt;<a href="mailto:jay@abbott.me.uk" class="gmail_msg" target="_blank">jay@abbott.me.uk</a>&gt; wrote:</div><br class="m_-6649614470166047773m_-8833943004122056022Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div dir="ltr" class="gmail_msg"><div class="m_-6649614470166047773m_-8833943004122056022markdown-here-wrapper gmail_msg"><p style="margin:0px 0px 1.2em!important" class="gmail_msg">Consider this code:</p>
<pre style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px" class="gmail_msg"><code class="m_-6649614470166047773m_-8833943004122056022language-swift m_-6649614470166047773m_-8833943004122056022hljs gmail_msg" style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;white-space:pre-wrap;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248) none repeat scroll 0% 0%"><span class="gmail_msg m_-6649614470166047773m_-8833943004122056022hljs-class"><span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">struct</span> <span class="gmail_msg m_-6649614470166047773m_-8833943004122056022hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">Pet</span> </span>{
    <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">let</span> name: <span class="m_-6649614470166047773m_-8833943004122056022hljs-type gmail_msg" style="color:rgb(68,85,136);font-weight:bold">String</span>
    <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">weak</span> <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">var</span> owner: <span class="m_-6649614470166047773m_-8833943004122056022hljs-type gmail_msg" style="color:rgb(68,85,136);font-weight:bold">Person</span>?

    <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">init</span>(name: <span class="m_-6649614470166047773m_-8833943004122056022hljs-type gmail_msg" style="color:rgb(68,85,136);font-weight:bold">String</span>, owner: <span class="m_-6649614470166047773m_-8833943004122056022hljs-type gmail_msg" style="color:rgb(68,85,136);font-weight:bold">Person</span>?) {
        <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">self</span>.name = name
        <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">self</span>.owner = owner
        owner?.pet = <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">self</span>
    }

    <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">mutating</span> <span class="m_-6649614470166047773m_-8833943004122056022hljs-func gmail_msg"><span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="gmail_msg m_-6649614470166047773m_-8833943004122056022hljs-title" style="color:rgb(153,0,0);font-weight:bold">transferOwnership</span><span class="m_-6649614470166047773m_-8833943004122056022hljs-params gmail_msg">(to newOwner: Person)</span> </span>{
        <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">let</span> previousOwner = owner
        owner = newOwner
        newOwner.pet = <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">self</span>
        <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">if</span>(previousOwner != <span class="gmail_msg m_-6649614470166047773m_-8833943004122056022hljs-built_in" style="color:rgb(0,134,179)">nil</span>) {
            previousOwner!.pet = <span class="gmail_msg m_-6649614470166047773m_-8833943004122056022hljs-built_in" style="color:rgb(0,134,179)">nil</span>
        }
    }

    <span class="m_-6649614470166047773m_-8833943004122056022hljs-func gmail_msg"><span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="gmail_msg m_-6649614470166047773m_-8833943004122056022hljs-title" style="color:rgb(153,0,0);font-weight:bold">feed</span><span class="m_-6649614470166047773m_-8833943004122056022hljs-params gmail_msg">()</span> </span>{
    }
}

<span class="gmail_msg m_-6649614470166047773m_-8833943004122056022hljs-class"><span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">class</span> <span class="gmail_msg m_-6649614470166047773m_-8833943004122056022hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">Person</span> </span>{
    <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">let</span> name: <span class="m_-6649614470166047773m_-8833943004122056022hljs-type gmail_msg" style="color:rgb(68,85,136);font-weight:bold">String</span>
    <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">var</span> pet: <span class="m_-6649614470166047773m_-8833943004122056022hljs-type gmail_msg" style="color:rgb(68,85,136);font-weight:bold">Pet</span>?

    <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">init</span>(name: <span class="m_-6649614470166047773m_-8833943004122056022hljs-type gmail_msg" style="color:rgb(68,85,136);font-weight:bold">String</span>) {
        <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">self</span>.name = name
    }

    <span class="m_-6649614470166047773m_-8833943004122056022hljs-func gmail_msg"><span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="gmail_msg m_-6649614470166047773m_-8833943004122056022hljs-title" style="color:rgb(153,0,0);font-weight:bold">givePetAway</span><span class="m_-6649614470166047773m_-8833943004122056022hljs-params gmail_msg">(to someone: Person)</span> </span>{
        <span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">if</span> pet != <span class="gmail_msg m_-6649614470166047773m_-8833943004122056022hljs-built_in" style="color:rgb(0,134,179)">nil</span> {
            pet!.transferOwnership(to: someone)
            <span class="gmail_msg m_-6649614470166047773m_-8833943004122056022hljs-comment" style="color:rgb(153,153,136);font-style:italic">//pet!.feed()</span>
        }
    }
}

<span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">let</span> bert = <span class="m_-6649614470166047773m_-8833943004122056022hljs-type gmail_msg" style="color:rgb(68,85,136);font-weight:bold">Person</span>(name: <span class="m_-6649614470166047773m_-8833943004122056022hljs-string gmail_msg" style="color:rgb(221,17,68)">&quot;Bert&quot;</span>)
<span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">let</span> ernie = <span class="m_-6649614470166047773m_-8833943004122056022hljs-type gmail_msg" style="color:rgb(68,85,136);font-weight:bold">Person</span>(name: <span class="m_-6649614470166047773m_-8833943004122056022hljs-string gmail_msg" style="color:rgb(221,17,68)">&quot;Ernie&quot;</span>)
<span class="m_-6649614470166047773m_-8833943004122056022hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">var</span> elmo = <span class="m_-6649614470166047773m_-8833943004122056022hljs-type gmail_msg" style="color:rgb(68,85,136);font-weight:bold">Pet</span>(name: <span class="m_-6649614470166047773m_-8833943004122056022hljs-string gmail_msg" style="color:rgb(221,17,68)">&quot;Elmo&quot;</span>, owner: <span class="gmail_msg m_-6649614470166047773m_-8833943004122056022hljs-built_in" style="color:rgb(0,134,179)">nil</span>)

elmo.transferOwnership(to: bert)
<span class="gmail_msg m_-6649614470166047773m_-8833943004122056022hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="m_-6649614470166047773m_-8833943004122056022hljs-string gmail_msg" style="color:rgb(221,17,68)">&quot;Bert&#39;s pet is <span class="m_-6649614470166047773m_-8833943004122056022hljs-subst gmail_msg" style="color:rgb(51,51,51);font-weight:bold;font-weight:normal">\(bert.pet)</span> - Ernie&#39;s pet is <span class="m_-6649614470166047773m_-8833943004122056022hljs-subst gmail_msg" style="color:rgb(51,51,51);font-weight:bold;font-weight:normal">\(ernie.pet)</span>&quot;</span>)

bert.givePetAway(to: ernie)
<span class="gmail_msg m_-6649614470166047773m_-8833943004122056022hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="m_-6649614470166047773m_-8833943004122056022hljs-string gmail_msg" style="color:rgb(221,17,68)">&quot;Bert&#39;s pet is <span class="m_-6649614470166047773m_-8833943004122056022hljs-subst gmail_msg" style="color:rgb(51,51,51);font-weight:bold;font-weight:normal">\(bert.pet)</span> - Ernie&#39;s pet is <span class="m_-6649614470166047773m_-8833943004122056022hljs-subst gmail_msg" style="color:rgb(51,51,51);font-weight:bold;font-weight:normal">\(ernie.pet)</span>&quot;</span>)
</code></pre><p style="margin:0px 0px 1.2em!important" class="gmail_msg">This works as expected, but if you uncomment <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="gmail_msg">pet!.feed()</code> in <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="gmail_msg">givePetAway(to:)</code> it will crash, because the mutating function modifies the two-way relationship between <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="gmail_msg">pet</code> and <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="gmail_msg">owner</code>.</p><p style="margin:0px 0px 1.2em!important" class="gmail_msg">In the code I use <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="gmail_msg">if pet != nil</code> to demonstrate, in your proposal for <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="gmail_msg">unwrap</code>, if I used it to <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="gmail_msg">unwrap pet</code> (a value-type, but accessed through <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="gmail_msg">self</code> so it can be modified after unwrapping because it’s not nil at the moment) the compiler would assume I could use it and <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="gmail_msg">pet.feed()</code> would crash, just as <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="gmail_msg">pet!.feed()</code> does now. In your proposal for type narrowing, it would be the same problem. This is like your <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="gmail_msg">foo.value</code> example from the proposal.</p><p style="margin:0px 0px 1.2em!important" class="gmail_msg">I don’t think you can get around the fact that the compiler can’t guarantee a type-narrowed or even unwrapped mutable value, which is why <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="gmail_msg">if let</code> works as it does with an immutable snapshot.</p><p style="margin:0px 0px 1.2em!important" class="gmail_msg">However, type narrowing for immutable values would still be good.</p></div></div></div></blockquote></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg">This isn&#39;t a problem of mutability, it&#39;s a problem due to the use of a reference type (Person); this is what the classes and concurrency section is supposed to be describing, but perhaps I haven&#39;t made it clear enough. So in the example you&#39;ve given self.pet can&#39;t be unwrapped because self is a reference type, thus you need to either use force unwrapping either with the unwrap! keyword or direct force unwrapping like you&#39;ve used (since behind the scenes it&#39;s the same thing).</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">You are right though that the resulting error isn&#39;t necessarily a concurrency issue, so I&#39;ll make a note of this for the proposed new error, and also clarify that the reference type restriction doesn&#39;t just apply to the property itself, but also to whatever it belongs to (and so-on up the chain, so if any part of foo.bar.a.b.c is a reference type it can&#39;t be soft unwrapped).</div></div>_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div>
_______________________________________________<br class="gmail_msg">swift-evolution mailing list<br class="gmail_msg"><a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg"></div></blockquote></div><br class="gmail_msg"></div></blockquote></div>