<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On 10 Nov 2016, at 21:42, Jay Abbott &lt;<a href="mailto:jay@abbott.me.uk" class="">jay@abbott.me.uk</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="markdown-here-wrapper" style=""><p style="margin:0px 0px 1.2em!important" class="">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=""><code class="language-swift hljs" 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;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="hljs-class"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">struct</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">Pet</span> </span>{
    <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> name: <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">String</span>
    <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">weak</span> <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">var</span> owner: <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">Person</span>?

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

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

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

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

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

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

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

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

bert.givePetAway(to: ernie)
<span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">"Bert's pet is <span class="hljs-subst" style="color:rgb(51,51,51);font-weight:bold;font-weight:normal">\(bert.pet)</span> - Ernie's pet is <span class="hljs-subst" style="color:rgb(51,51,51);font-weight:bold;font-weight:normal">\(ernie.pet)</span>"</span>)
</code></pre><p style="margin:0px 0px 1.2em!important" class="">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="">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="">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="">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="">owner</code>.</p><p style="margin:0px 0px 1.2em!important" class="">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="">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="">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="">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="">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="">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="">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="">foo.value</code> example from the proposal.</p><p style="margin:0px 0px 1.2em!important" class="">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="">if let</code> works as it does with an immutable snapshot.</p><p style="margin:0px 0px 1.2em!important" class="">However, type narrowing for immutable values would still be good.</p></div></div></div></blockquote></div><div class="">This isn't a problem of mutability, it'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't made it clear enough. So in the example you've given self.pet can'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've used (since behind the scenes it's the same thing).</div><div class=""><br class=""></div><div class="">You are right though that the resulting error isn't necessarily a concurrency issue, so I'll make a note of this for the proposed new error, and also clarify that the reference type restriction doesn'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't be soft unwrapped).</div></body></html>