<html><head><style>
body {
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        padding:1em;
        margin:auto;
        background:#fefefe;
}

h1, h2, h3, h4, h5, h6 {
        font-weight: bold;
}

h1 {
        color: #000000;
        font-size: 28pt;
}

h2 {
        border-bottom: 1px solid #CCCCCC;
        color: #000000;
        font-size: 24px;
}

h3 {
        font-size: 18px;
}

h4 {
        font-size: 16px;
}

h5 {
        font-size: 14px;
}

h6 {
        color: #777777;
        background-color: inherit;
        font-size: 14px;
}

hr {
        height: 0.2em;
        border: 0;
        color: #CCCCCC;
        background-color: #CCCCCC;
    display: inherit;
}

p, blockquote, ul, ol, dl, li, table, pre {
        margin: 15px 0;
}

a, a:visited {
        color: #4183C4;
        background-color: inherit;
        text-decoration: none;
}

#message {
        border-radius: 6px;
        border: 1px solid #ccc;
        display:block;
        width:100%;
        height:60px;
        margin:6px 0px;
}

button, #ws {
        font-size: 12 pt;
        padding: 4px 6px;
        border-radius: 5px;
        border: 1px solid #bbb;
        background-color: #eee;
}

code, pre, #ws, #message {
        font-family: Monaco;
        font-size: 10pt;
        border-radius: 3px;
        background-color: #F8F8F8;
        color: inherit;
}

code {
        border: 1px solid #EAEAEA;
        margin: 0 2px;
        padding: 0 5px;
}

pre {
        border: 1px solid #CCCCCC;
        overflow: auto;
        padding: 4px 8px;
}

pre > code {
        border: 0;
        margin: 0;
        padding: 0;
}

#ws { background-color: #f8f8f8; }


.bloop_markdown table {
border-collapse: collapse;  
font-family: Helvetica, arial, freesans, clean, sans-serif;  
color: rgb(51, 51, 51);  
font-size: 15px; line-height: 25px;
padding: 0; }

.bloop_markdown table tr {
border-top: 1px solid #cccccc;
background-color: white;
margin: 0;
padding: 0; }
     
.bloop_markdown table tr:nth-child(2n) {
background-color: #f8f8f8; }

.bloop_markdown table tr th {
font-weight: bold;
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }

.bloop_markdown table tr td {
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }

.bloop_markdown table tr th :first-child, table tr td :first-child {
margin-top: 0; }

.bloop_markdown table tr th :last-child, table tr td :last-child {
margin-bottom: 0; }

.bloop_markdown blockquote{
  border-left: 4px solid #dddddd;
  padding: 0 15px;
  color: #777777; }
  blockquote > :first-child {
    margin-top: 0; }
  blockquote > :last-child {
    margin-bottom: 0; }

code, pre, #ws, #message {
    word-break: normal;
    word-wrap: normal;
}

hr {
    display: inherit;
}

.bloop_markdown :first-child {
    -webkit-margin-before: 0;
}

code, pre, #ws, #message {
    font-family: Menlo, Consolas, Liberation Mono, Courier, monospace;
}


.send { color:#77bb77; }
.server { color:#7799bb; }
.error { color:#AA0000; }</style></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="bloop_markdown"><p>I disagree with some of your points. Do begin with, I don’t think we should disallow capturing the generic type parameter, because I think there might be a good way to prevent parameterization of nested protocols.</p>

<p>To me this only feels like a natural consequence of nesting protocols anyways. To achieve this we have to provide an explicit associated type which will have a default type that refers to the captured outer generic type parameter. At this point we discover another issue that we cannot disambiguate generic type parameter like associated types yet and would be forced to name the associated type of the protocol differently.</p>

<pre><code class="swift">struct Generic&lt;T&gt; {
  protocol P {  
    associatedtype R = T  
    func f() -&gt; R  
  }
}
</code></pre>

<p>As you can see I didn’t include the variable in this example, because existential are orthogonal this issue. David Hart and I still want to write a proposal to allow the <code>where</code> clause on typealiases - maybe after the forum officially launches.</p>

<p>Above I said that there is an issue and provided an example that would solve that issue with todays syntax, but I’d rather expand this idea. Consider this syntax of a generic type and a protocol with an associated type.</p>

<pre><code class="swift">protocol Proto {
  associatedtype Element
}

Proto.Element // This is an error like this, but it's still allowed in a generic context

func function&lt;P : Proto&gt;(_: P) where P.Element == Int {}

protocol OtherProto : Proto where Element == Int {}

struct Test&lt;Element&gt; {}

extension Test where Element == Int {}

Test.Element // Can/should we allow this?
</code></pre>

<p>If we could allow this in Swift then the above example with the nested protocol could be disambiguated nicely.</p>

<pre><code class="swift">struct Generic&lt;T&gt; {
  protocol P {  
    associatedtype T = Generic.T  
    func f() -&gt; T  
  }
}
</code></pre>

<p>Remember that <code>Generic.T</code> is only the default for <code>P.T</code> if you don’t set it yourself but when you conform or use that that protocol (in a generic context) you can still set it differntly.</p>

<p>This consequence disallows protocol parameterization through nesting in a generic types, but still behaves very similar to nested generic types:</p>

<pre><code class="swift">struct Test&lt;T&gt; {
  struct NonGeneric {
    var t: T
  }

  struct Generic&lt;R&gt; {
    var t: T
    var r: R
  }
}

_ = Test&lt;String&gt;.NonGeneric(t: "😎")
_ = Test&lt;String&gt;.Generic&lt;Int&gt;(t: "🤓", r: 42)
</code></pre>

<p>——</p>

<p>And for the existential variable inside <code>Genric</code> it really should be something like this (when the where clause is allowed and if we can refer differently to generic type parameters as well):</p>

<pre><code class="swift">struct Generic&lt;T&gt; {
    …
    typealias PConstrainedByT = P where T == Self.T
    var object: PConstrainedByT
}
</code></pre>

<p></p></div><div class="bloop_original_html"><style>body{font-family:Helvetica,Arial;font-size:13px}</style><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><br></div> <br> <div id="bloop_sign_1514458702433282816" class="bloop_sign"></div> <br><p class="airmail_on">Am 27. Dezember 2017 um 19:53:36, Karl Wagner via swift-evolution (<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>) schrieb:</p> <blockquote type="cite" class="clean_bq"><span><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div></div><div>



<title></title>


Yeah I wrote that proposal. I eventually stripped it down to just
disallow all capturing, but it was still not selected by the core
team for review ¯\_(ツ)_/¯
<div class=""><br class=""></div>
<div class="">As for capturing semantics, once you start working
through use-cases, it’s becomes clear that it's going to require
generalised existentials. Otherwise, how would you use a
Generic&lt;T&gt;.P?</div>
<div class=""><br class=""></div>
<div class="">struct Generic&lt;T&gt; {</div>
<div class="">&nbsp; &nbsp; protocol P { func f() -&gt; T }</div>
<div class=""><br class=""></div>
<div class="">&nbsp; &nbsp; var object: P // uh-oh! ‘Generic
protocol can only be used as a generic parameter constraint'</div>
<div class="">}</div>
<div class=""><br class=""></div>
<div class="">So, you would need to add a generic parameter to
actually <i class="">use</i> P from within Generic&lt;T&gt;, which
of course limits you to a single concrete type of P:</div>
<div class=""><br class=""></div>
<div class="">struct Generic&lt;T, TypeOfP&gt; where TypeOfP:
Self.P { &nbsp; &nbsp; &nbsp;// Could this even work? What if P
captures TypeOfP?</div>
<div class="">&nbsp; &nbsp; protocol P { /* … */ }</div>
<div class="">&nbsp; &nbsp; var object: TypeOfP</div>
<div class="">}</div>
<div class=""><br class=""></div>
<div class="">Which is just yucky.</div>
<div class=""><br class=""></div>
<div class="">Ideally, the type of ‘object’ should be ‘Any&lt;P
where P.T == T&gt;’, to express that it can be any conforming type
with the appropriate constraints. You wouldn’t need to write that
all out; we could infer that capturing is equivalent to a same-type
constraint (or perhaps one of these “generalised supertype
constraints” that were pitched recently). But we can’t express
those kinds of existentials everywhere in the type-system today, so
most examples of capturing fall down pretty quickly.</div>
<div class=""><br class=""></div>
<div class="">- Karl<br class="">
<div><br class="">
<blockquote type="cite" class="">
<div class="">On 25. Dec 2017, at 03:56, Slava Pestov via
swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<div class="">There was a proposal to allow protocols to be nested
inside types at one point but it didn’t move forward.<br class="">
<br class="">
Basically, if the outer type is a non-generic class, struct or
enum, there’s no conceptual difficulty at all.<br class="">
<br class="">
If the outer type is a generic type or another protocol, you have a
problem where the inner protocol can reference generic parameters
or associated types of the outer type. This would either have to be
banned, or we would need to come up with coherent semantics for
it:<br class="">
<br class="">
struct Generic&lt;T&gt; {<br class="">
&nbsp;protocol P {<br class="">
&nbsp;&nbsp;&nbsp;func f() -&gt; T<br class="">
&nbsp;}<br class="">
}<br class="">
<br class="">
struct Conforms : Generic&lt;Int&gt;.P {<br class="">
&nbsp;func f() -&gt; Int { … } // Like this?<br class="">
}<br class="">
<br class="">
let c = Conforms()<br class="">
c is Generic&lt;String&gt;.P // is this false? Ie, are
Generic&lt;Int&gt;.P and Generic&lt;String&gt;.P different
protocols?<br class="">
<br class="">
Slava<br class="">
<br class="">
<blockquote type="cite" class="">On Dec 24, 2017, at 6:53 PM,
Kelvin Ma via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">
<br class="">
is there a reason why it’s not allowed to nest a protocol
declaration inside another type?<br class="">
_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></blockquote>
<br class="">
_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div>
</div>
</blockquote>
</div>
<br class=""></div>


_______________________________________________<br>swift-evolution mailing list<br>swift-evolution@swift.org<br>https://lists.swift.org/mailman/listinfo/swift-evolution<br></div></div></span></blockquote></div><div class="bloop_markdown"><p></p></div></body></html>