<div dir="ltr">This is certainly a detailed and well-considered proposal.<div><br></div><div>I don&#39;t think the struct functionality makes much sense. There are two ways you can use the struct&lt;...&gt; construct:</div><div><br></div><div>1. struct&lt;SomeConcreteStruct, Protocol1, Protocol2&gt;. In this case the struct&lt;...&gt; representation is unnecessary; the protocols that are available to the user are known at compile-time, and structs can&#39;t have subtypes that conform to additional protocols like classes can. There is an example marked &quot;func boo(value: struct&lt;SomeStruct&gt;) /* equivalent to */ func boo(value: SomeStruct)&quot;; my question is why having more than two ways to express the same idea makes the language better, easier to use, etc.</div><div><br></div><div>2. struct&lt;T, Protocol1, Protocol2&gt;. In this case struct&lt;...&gt; is being used as an add-on to the generics system to denote a &#39;must be value type&#39; constraint. However, I think a &#39;T : class&#39;-like &#39;struct&#39; constraint makes more sense, both because it fits better with the existing &#39;class&#39; constraint and because it can be used anywhere the generic system allows a type parameter to be constrained. A generic &#39;struct&#39; constraint would give the currently generics system as much expressive power as struct&lt;...&gt;.</div><div><br></div><div>Overall, rather than having this be a separate feature I think it should be developed as part of the &quot;Generalized Existentials&quot; feature that is already on the roadmap for Swift 3. The cases where adding class&lt;...&gt;, struct&lt;...&gt;, etc can improve expressive power are covered by allowing variables to take existential types with constraints. The one big feature that Generalized Existentials should absorb from this proposal is allowing the representation of a concrete class type with protocol constraints (&lt;MyClass, SomeProtocol, AnotherProtocol&gt;).</div><div><br></div><div>Best,</div><div>Austin</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, May 13, 2016 at 5:16 PM, Matthew Johnson via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><span class=""><blockquote type="cite"><div>On May 13, 2016, at 2:14 PM, Adrian Zubarev via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br><div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;margin:0px"><blockquote type="cite">As we can(as example) expect that in 3rd party code someone will do: <br><br>extension StructA: ExtraProtocol1 { <br>func bar() {} <br>} <br><br>extension StructB: ExtraProtocol2 { <br>func blort() {} <br>} </blockquote></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><span style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">Can we really do that? I mean, I thought about that myself but I came to the conclusion that this scenario is like: I was to lazy to couple this structs to my library protocols, will you do that for me?</span><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Sure one could think that this protocols might be optional but the `<span style="font-family:&#39;helvetica Neue&#39;,helvetica">f(p: MyProtocol)</span>` function will cover this scenario.</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Another interesting side-effect `struct&lt;&gt;`, `class&lt;&gt;` and `enum&lt;&gt;` will allow us to do is to distinguish between value and reference types for generics. I tried this differentiation types with protocols like `AnyReference` and `AnyValue` in another topic before (<a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160502/016286.html" target="_blank"><span>Should we rename &quot;class&quot; when referring to protocol conformance?</span></a>), but I kinda like this new approach.</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Here is what I mean in detail:</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">protocol SomeProtocol /* we can’t constraint it to value types at the moment, only `class`es works */ {}</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">func foo&lt;T&gt;(value: struct&lt;T, SomeProtocol&gt;) { /* do some work */ }</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">This function is pretty neat. (1) You can force the library user to create a struct with conformance to `SomeProtocol`. (2) This approach will accept any struct which conforms to that protocol.</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">As I said in the protocol comment above protocols can only be constrained to classes at the moment, and this might change in the future. If we also had some sort of things for generics so the function from above might have looked like this:</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">func foo&lt;T: struct where T: SomeProtocol&gt;(value: T) {}</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">But it seems that such a thing won’t ever happen to Swift.</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Basically `struct&lt;&gt;`, `class&lt;&gt;` and `enum&lt;&gt;` will just enable this for us. `all&lt;&gt;` would accept any type at its first element.</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">func foo&lt;T /* add more constraints here */ &gt;(value: all&lt;T, SomeProtocol&gt;) { /* T could be a reference type or value type */ }</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">That been said, `all&lt;&gt;` could replace `protocol&lt;&gt;` where it is composed from protocols. `all&lt;&gt;` can only be used as a generic constraints if the first element is a protocol or a reference type.</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">@Matthew: isn’t this somehow a step towards (generic) `PureValue` types?</div></div></blockquote><div><br></div></span><div>No.  These say nothing about semantics.  PureValue is all about the semantics of a type and has nothing to do with what mechanism is used to implement the type.</div><div><div class="h5"><br><blockquote type="cite"><div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">struct A&lt;T&gt; {</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">    var value: struct&lt;T&gt; // if we drop the strict rule of at least one protocols</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">}</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">How does it sound to you?</div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"> </div><div style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div><div style="font-family:helvetica,arial;font-size:13px">-- <br>Adrian Zubarev<br>Sent with Airmail</div></div><br><p>Am 13. Mai 2016 bei 20:34:59, Vladimir.S (<a href="mailto:svabox@gmail.com" target="_blank">svabox@gmail.com</a>) schrieb:</p><blockquote type="cite"><span><div><div></div><div>Hmm..<span> </span><br><br>What about such synthetic scenario:<span> </span><br><br>at the moment of writing our code we have:<span> </span><br><br>public protocol MyProtocol {<span> </span><br>func foo()<span> </span><br>}<span> </span><br><br>public struct StructA:MyProtocol {<span> </span><br>func foo()<span> </span><br>}<span> </span><br><br>public struct StructB:MyProtocol {<span> </span><br>func foo()<span> </span><br>}<span> </span><br><br>and have<span> </span><br><br>public protocol ExtraProtocol1 {<span> </span><br>func bar()<span> </span><br>}<span> </span><br><br>public protocol ExtraProtocol2 {<span> </span><br>func blort()<span> </span><br>}<span> </span><br><br>then we actually can have such code:<span> </span><br><br>func f(p: MyProtocol) {<span> </span><br>if let a = p as? struct&lt;StructA, ExtraProtocol1&gt; {<span> </span><br>a.foo()<span> </span><br>a.bar()<span> </span><br>}<span> </span><br>else<span> </span><br>if let b = p as? struct&lt;StructB, ExtraProtocol2&gt; {<span> </span><br>b.foo()<span> </span><br>b.blort()<span> </span><br>}<span> </span><br>}<span> </span><br><br><br><br><br>On 13.05.2016 20:50, Adrian Zubarev via swift-evolution wrote:<span> </span><br>&gt;&gt; &#39;struct&lt;&gt;&#39; does seem redundant unless it becomes subtypeable. If<span> </span><br>&gt;&gt; you want a struct which conforms to several protocols, protocol&lt;&gt;<span> </span><br>&gt;&gt; already covers this.<span> </span><br>&gt;&gt;<span> </span><br>&gt;&gt; I think this is not correct. Lets check this example:<span> </span><br>&gt;&gt;<span> </span><br>&gt;&gt; func foo(value: SomeProtocol) {<span> </span><br>&gt;&gt;<span> </span><br>&gt;&gt; if let a = value as? struct&lt;StructA, SomeProtocol&gt; { /* do<span> </span><br>&gt;&gt; something with a */ }<span> </span><br>&gt;&gt;<span> </span><br>&gt;&gt; else if let b = value as? struct&lt;StructB, SomeProtocol&gt; { /* do<span> </span><br>&gt;&gt; something with b */ }<span> </span><br>&gt;&gt;<span> </span><br>&gt;&gt; }<span> </span><br>&gt;&gt;<span> </span><br>&gt;&gt; In this scenario you’ll be able to access properties and functions<span> </span><br>&gt;&gt; from `StructA` or `StructB` which might not be covered by<span> </span><br>&gt;&gt; `SomeProtocol`. Everything is merged nicely into one instance. But<span> </span><br>&gt;&gt; you are right it depends on the use-case.<span> </span><br>&gt;&gt;<span> </span><br>&gt;&gt;<span> </span><br>&gt;&gt; There is no need to include the protocol here. Just do this:<span> </span><br>&gt;&gt;<span> </span><br>&gt;&gt; if let a = value as? StructA { use a }<span> </span><br>&gt;&gt;<span> </span><br>&gt; Whoops, I forgot that this will do the trick. I apologize for any confusion<span> </span><br>&gt; here, you are totally right.<span> </span><br>&gt;<span> </span><br>&gt; That been said, do we really need `type&lt;&gt;` aka. `all&lt;&gt;` for value types? I<span> </span><br>&gt; need to rethink this part of the proposal. Is there any use-case where we<span> </span><br>&gt; would need this (any scenario for the future Swift version also counts)?<span> </span><br>&gt;<span> </span><br>&gt; If we had `all&lt;&gt;` in Swift already for extendable reference types and one<span> </span><br>&gt; day structs would become subtypeable, this wouldn’t be a huge problem to<span> </span><br>&gt; upgrade `all&lt;&gt;` for structs I guess.<span> </span><br>&gt;<span> </span><br>&gt; --<span> </span><br>&gt; Adrian Zubarev<span> </span><br>&gt; Sent with Airmail<span> </span><br>&gt;<span> </span><br>&gt;<span> </span><br>&gt;<span> </span><br>&gt; _______________________________________________<span> </span><br>&gt; swift-evolution mailing list<span> </span><br>&gt; <a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><span> </span><br>&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><span> </span><br>&gt;<span> </span><br></div></div></span></blockquote></div><span style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">_______________________________________________</span><br style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">swift-evolution mailing list</span><br style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><a href="mailto:swift-evolution@swift.org" style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank">swift-evolution@swift.org</a><br style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div></div></div><br></div><br>_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br></blockquote></div><br></div>