<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br></div><div><div><br><br>Sent from my iPhone</div>On Jan 11, 2017, at 14:57, Anton Zhilin via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><div dir="ltr"><div class="markdown-here-wrapper" style=""><p style="margin:0px 0px 1.2em!important">Wouldn’t protocols be a better solution in this case? If little to no logic can be shared between enum cases, why have the enum in the first place?</p>
<p style="margin:0px 0px 1.2em!important">Your variant:</p>
<pre style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-swift" style="font-size:0.85em;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)"><span class="hljs-class"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">protocol</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">State</span> </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">react</span><span class="hljs-params">(to event: Event)</span>
}

<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">enum</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">AuthenticationState</span>: <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">State</span>, <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">CustomStringConvertible</span> </span>{

    <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">case</span> invalid {
        <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">var</span> description: <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">return</span> <span class="hljs-string" style="color:rgb(221,17,68)">"Authentication invalid."</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">react</span><span class="hljs-params">(to event: Event)</span> </span>{
            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">switch</span> event {

            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">case</span> <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> login <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">as</span> <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">UserLoggedIn</span>:
                <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">self</span> = .validated(token: login.token)
            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">default</span>:
                <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">break</span>
            }
        }
    }

    <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">case</span> expired(<span class="hljs-number" style="color:rgb(0,128,128)">_</span> expiration: <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">Date</span>) {
        <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">var</span> description: <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">return</span> <span class="hljs-string" style="color:rgb(221,17,68)">"Authentication expired at <span class="hljs-subst" style="color:rgb(51,51,51);font-weight:bold;font-weight:normal">\(expiration)</span>."</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">react</span><span class="hljs-params">(to event: Event)</span> </span>{
            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">switch</span> event {
            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">case</span> <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> refreshed <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">as</span> <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">TokenRefreshed</span>:

                <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">self</span> = .validated(token: refreshed.token)

            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">default</span>:
                <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">break</span>
            }
        }
    }

    <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">case</span> validated(token: <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> description: <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">return</span> <span class="hljs-string" style="color:rgb(221,17,68)">"The authentication token is <span class="hljs-subst" style="color:rgb(51,51,51);font-weight:bold;font-weight:normal">\(token)</span>."</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">react</span><span class="hljs-params">(to event: Event)</span> </span>{
            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">switch</span> event {

            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">case</span> <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> expiration <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">as</span> <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">TokenExpired</span>:
                <span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">"Expiring token: <span class="hljs-subst" style="color:rgb(51,51,51);font-weight:bold;font-weight:normal">\(token)</span>"</span>)
                <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">self</span> = .expired(expiration.date)
            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">case</span> <span class="hljs-number" style="color:rgb(0,128,128)">_</span> <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">as</span> <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">TokenRejected</span>:
                <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">self</span> = .invalid
            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">case</span> <span class="hljs-number" style="color:rgb(0,128,128)">_</span> <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">as</span> <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">UserLoggedOut</span>:
                <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">self</span> = .invalid
            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">default</span>:
                <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">break</span>
            }
        }
    }

}
</code></pre>
<p style="margin:0px 0px 1.2em!important">My suggestion:</p>
<pre style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-swift" style="font-size:0.85em;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)">public <span class="hljs-class"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">protocol</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">State</span> </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">react</span><span class="hljs-params">(to event: Event)</span>
}

@<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">closed</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">protocol</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">AuthenticationState</span> : <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">State</span>, <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">CustomStringConvertible</span> </span>{ }

<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">InvalidAuthenticationState</span> : <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">AuthenticationState</span> </span>{
    <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">var</span> description: <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">return</span> <span class="hljs-string" style="color:rgb(221,17,68)">"Authentication invalid."</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">react</span><span class="hljs-params">(to event: Event)</span> </span>{
        <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">switch</span> event {

        <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">case</span> <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> login <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">as</span> <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">UserLoggedIn</span>:
            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">self</span> = .validated(token: login.token)
        <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">default</span>:
            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">break</span>
        }
    }
}

<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">ExpiredAuthenticationState</span> : <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">AuthenticationState</span> </span>{
    <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">var</span> expiration: <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">Date</span>

    <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">var</span> description: <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">return</span> <span class="hljs-string" style="color:rgb(221,17,68)">"Authentication expired at <span class="hljs-subst" style="color:rgb(51,51,51);font-weight:bold;font-weight:normal">\(expiration)</span>."</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">react</span><span class="hljs-params">(to event: Event)</span> </span>{
        <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">switch</span> event {
        <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">case</span> <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> refreshed <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">as</span> <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">TokenRefreshed</span>:

            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">self</span> = .validated(token: refreshed.token)

        <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">default</span>:
            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">break</span>
        }
    }
}

<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">ValidatedAuthenticationState</span> : <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">AuthenticationState</span> </span>{
    <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">var</span> token: <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> description: <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">return</span> <span class="hljs-string" style="color:rgb(221,17,68)">"The authentication token is <span class="hljs-subst" style="color:rgb(51,51,51);font-weight:bold;font-weight:normal">\(token)</span>."</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">react</span><span class="hljs-params">(to event: Event)</span> </span>{
        <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">switch</span> event {

        <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">case</span> <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> expiration <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">as</span> <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">TokenExpired</span>:
            <span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">"Expiring token: <span class="hljs-subst" style="color:rgb(51,51,51);font-weight:bold;font-weight:normal">\(token)</span>"</span>)
            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">self</span> = .expired(expiration.date)
        <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">case</span> <span class="hljs-number" style="color:rgb(0,128,128)">_</span> <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">as</span> <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">TokenRejected</span>:
            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">self</span> = .invalid
        <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">case</span> <span class="hljs-number" style="color:rgb(0,128,128)">_</span> <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">as</span> <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">UserLoggedOut</span>:
            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">self</span> = .invalid
        <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">default</span>:
            <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">break</span>
        }
    }
}
</code></pre>
<p style="margin:0px 0px 1.2em!important">If <code style="font-size:0.85em;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">AuthenticationState</code> is not <code style="font-size:0.85em;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">public</code>, then compiler can make an optimization and turn existentials and indirect calls into an enum, essentially.<br>We can even split <code style="font-size:0.85em;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">public</code> protocols into <code style="font-size:0.85em;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">open</code> and <code style="font-size:0.85em;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">public</code>, as we did with classes, to allow for expressing this intent more explicitly.</p>
</div></div></div></blockquote><div>I don't understand the lines in the struct version where you assign something to `self`. What is ".invalid", for example? I thought you'd removed the enum altogether.</div><div><br></div><div><br></div><br><blockquote type="cite"><div dir="ltr"><div class="markdown-here-wrapper" style=""><p style="margin:0px 0px 1.2em!important">But pattern matching on structs is impossible—we can change that with a separate proposal. For example, we can allow destructuring structs/enums/classes by any combination of their properties:</p>
<pre style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-swift" style="font-size:0.85em;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)"><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">S</span> </span>{
    <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">var</span> foo: <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">Int</span>
    <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">var</span> bar: <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">Double</span>
    <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">var</span> buz: <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">return</span> <span class="hljs-string" style="color:rgb(221,17,68)">"42"</span> }
}

<span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> s = <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">S</span>(foo: <span class="hljs-number" style="color:rgb(0,128,128)">42</span>, bar: <span class="hljs-number" style="color:rgb(0,128,128)">42.0</span>)

<span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">let</span> <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">S</span>(foo: x, buz: z) = s</code></pre></div></div></blockquote>I was under the impression that we could switch over anything that had the `~=` operator defined. Is that not the case?<div><br></div><div>- Dave Sweeris</div></body></html>