<div dir="ltr">(inline)<br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, May 27, 2016 at 10:09 AM, Thorsten Seitz <span dir="ltr">&lt;<a href="mailto:tseitz42@icloud.com" target="_blank">tseitz42@icloud.com</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>Am 27.05.2016 um 18:36 schrieb Austin Zheng &lt;<a href="mailto:austinzheng@gmail.com" target="_blank">austinzheng@gmail.com</a>&gt;:</div><br><div><div style="word-wrap:break-word"><div>I think the parentheses are the fundamental aspect of the suggestion :).</div><div><br></div><div>Let me turn the question around. If tuples were declared like this:</div><div><br></div><div>let myTuple : Int, String, Bool = (10, &quot;hello&quot;, false)</div><div><br></div><div>would the type be more or less readable? I find it a lot more difficult to immediately parse than:</div><div><br></div><div>let myTuple : (Int, String, Bool) = (10, &quot;hello&quot;, false)</div><div><br></div><div>At the same time, nobody&#39;s complained about tuple type parentheses getting in the way. </div></div></div></blockquote><div><br></div></span>Parentheses are the hallmark of tuples, so its natural to expect them around the tuple type as well :-)</div></div></blockquote><div><br></div><div>But this is a circular definition. Why can&#39;t parentheses be the hallmark of structural types, not just tuples? After all, one of the big complaints against the Any&lt;&gt; and protocol&lt;&gt; syntaxes has been that angle brackets belong to generics already.</div><div> </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"><div><br></div><div><span class=""><br><blockquote type="cite"><div><div style="word-wrap:break-word"><div><br></div><div>We&#39;re trying to establish a syntax that will hopefully be used for things significantly more complicated than tuple definitions, which are just a list of types. I think readability is a major concern. Typealiases should be supported, but they shouldn&#39;t be required to make the feature useable.</div><div><br></div><div>Finally, wouldn&#39;t we need some delimiter for nested existential definitions anyways? Now you have the confusing situation where the outside definition has no delimiters, but the inside ones do:</div></div></div></blockquote><div><br></div></span>Why is this confusing? The expression `2 * (3 + 1)` also has parentheses only around the part which needs them. </div><div>Probably no one would require having to write `(2 * (3 + 1))` for consistency.</div></div></blockquote><div><br></div><div>You can make the same argument about tuples.</div><div> </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"><div></div><div> </div><div><span class=""><blockquote type="cite"><div><div style="word-wrap:break-word"><div><br></div><div>// Why does the inner existential look fundamentally different than the outer one?</div><div>// Not to mention, visually parsing the boundaries of this type when you look at it in a function signature</div><div>let x : Protocol1, Protocol2, (Protocol 3 where .Foo == Int) where Protocol2.Bar : Baz</div></div></div></blockquote><div><br></div></span><div><div>Using `&amp;` instead of `,` will make it look better, too, IMHO:</div><div><br></div><div>let x: Protocol1 &amp; Protocol2 &amp; (Protocol3 where .Foo == Int) where Protocol2.Bar: Baz</div></div></div></div></blockquote><div><br></div><div>I agree that &#39;&amp;&#39; is better - my mistake. I still submit my concerns about legibility.</div><div> </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"><div><div><div><br></div><div>or better (removing the asymmetry):</div><div><br></div><div>let x: Protocol1 &amp; (Protocol2 where .Bar : Baz) &amp; (Protocol3 where .Foo == Int)</div><div><br></div><div>or putting all constraints in the where clause for the whole expression:</div><div><br></div><div>let x: Protocol1 &amp; Protocol2 &amp; Protocol3 where Protocol2.Bar: Baz, Protocol3.Foo == Int</div></div></div></div></blockquote><div><br></div><div>I would much rather have parentheses enclosing the outside type than force people to structure their requirements a certain way.</div><div> </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"><div><span class="HOEnZb"><font color="#888888"><div><br></div><div><div><br></div><div>-Thorsten</div></div></font></span><div><div class="h5"><div><br></div><br><blockquote type="cite"><div><div style="word-wrap:break-word"><div><br></div><div>I hope that explains my reasoning.</div><div><br></div><div>Best,</div><div>Austin</div><div><br></div><br><div><blockquote type="cite"><div>On May 27, 2016, at 9:28 AM, Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" target="_blank">matthew@anandabits.com</a>&gt; wrote:</div><br><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br><br>Sent from my iPad</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br>On May 27, 2016, at 11:18 AM, Austin Zheng &lt;<a href="mailto:austinzheng@gmail.com" target="_blank">austinzheng@gmail.com</a>&gt; wrote:<br><br></div><blockquote type="cite" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div>Here&#39;s a strawman idea.<div><br></div><div>What if we go with &#39;&amp;&#39; and &#39;where&#39;, but we enclose the whole thing in parentheses?</div><div><br></div><div>(class &amp; Protocol1 &amp; Protocol2 where .Foo == Int, .Bar : Baz)</div><div><br></div><div>There are a couple of reasons I propose this syntax:</div><div><br></div><div>- It makes it very clear where the definition of the type begins and ends. I understand people really despise angle brackets, but I really want some way to visually delineate the boundaries of the type. Plus, I imagine it makes syntax a little easier to parse and preemptively forbids some ambiguities.</div><div><br></div><div>- It&#39;s a structural, not nominal, type, like a tuple, so it uses parens as well. This reserves &quot;&lt;&quot; and &quot;&gt;&quot; for generic types.</div><div><br></div><div>- The &#39;&amp;&#39; is easily understood - &quot;Protocol1&quot; *and* &quot;Protocol2&quot;. It&#39;s also a signal that order doesn&#39;t matter - just like how order matters with things that use commas, like argument lists, tuples, and array members, order doesn&#39;t generally matter with bitwise or logical &#39;and&#39; operators.</div><div><br></div><div>- If we ever decide to have union types, we have a very elegant third form of nominal type syntax that naturally falls out: (MyClass1 | MyClass2 | MyClass3).</div><div><br></div><div>Thoughts?</div></div></blockquote><div style="font-family:Helvetica;font-size:12px;font-style: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;font-size:12px;font-style: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">Generally in favor.  But I would not require the parentheses.  I believe they would be allowed optionally automatically, just as (Int) is the same as Int (because single element tuples don&#39;t exist and the underlying type is used directly instead).  It seems better to leave parentheses up to a matter of style.</span><div style="font-family:Helvetica;font-size:12px;font-style: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;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br><blockquote type="cite"><div><div><br></div><div>Austin</div><div><br></div><div><br><div><blockquote type="cite"><div>On May 27, 2016, at 9:07 AM, Thorsten Seitz 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="word-wrap:break-word"><br><div><blockquote type="cite"><div>Am 27.05.2016 um 16:54 schrieb Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" target="_blank">matthew@anandabits.com</a>&gt;:</div><br><div><blockquote type="cite" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div><br>On May 27, 2016, at 8:18 AM, Thorsten Seitz 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="word-wrap:break-word">Personally I think `&amp;` is more lightweight (and it is established in other languages like Ceylon and Typescript) and `where` is more expressive (and established in Swift for introducing constraints), so I would stay with these.</div></div></blockquote><div style="font-family:Helvetica;font-size:12px;font-style: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;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">I agree.  If we can make `&amp;` with `where` work syntactically it would be nice to go in this lighter weight direction.  If we decide to do that the question then becomes what to do with `protocol`.  Would it be feasible to replace it with `&amp;` in Swift 3 if we decide on that direction?</div></div></blockquote><div><br></div>Yep. `protocol` should be replaced with `&amp;` in that case.</div><div><br></div><div>-Thorsten</div><div><br></div><div><br><blockquote type="cite"><div><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><blockquote type="cite" style="font-family:Helvetica;font-size:12px;font-style: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="word-wrap:break-word"><div><br></div><div>-Thorsten<br><div><br></div><div><br><div><blockquote type="cite"><div>Am 27.05.2016 um 14:34 schrieb Vladimir.S &lt;<a href="mailto:svabox@gmail.com" target="_blank">svabox@gmail.com</a>&gt;:</div><br><div><span style="font-family:Helvetica;font-size:12px;font-style: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">Btw, in case we have `where` keyword in syntax related to types/protocols (when defining constrains. and not some symbol like &#39;&gt;&gt;&#39;.. don&#39;t know, for example), why we can&#39;t have &#39;and&#39; keyword also when discuss the syntax of type/protocol conjunction?</span><br style="font-family:Helvetica;font-size:12px;font-style: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;font-size:12px;font-style: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">I.e.</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br style="font-family:Helvetica;font-size:12px;font-style: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;font-size:12px;font-style: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">let x: P and Q</span><br style="font-family:Helvetica;font-size:12px;font-style: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;font-size:12px;font-style: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">let x: P and Q where P.T == Q.T</span><br style="font-family:Helvetica;font-size:12px;font-style: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;font-size:12px;font-style: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">let x: P and Q and R</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br style="font-family:Helvetica;font-size:12px;font-style: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;font-size:12px;font-style: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">or, for consistency, as I understand it, we should have</span><br style="font-family:Helvetica;font-size:12px;font-style: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;font-size:12px;font-style: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">let x: P &amp; Q &gt;&gt; P.T == Q.T</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br style="font-family:Helvetica;font-size:12px;font-style: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;font-size:12px;font-style: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">On 27.05.2016 11:55, Thorsten Seitz via swift-evolution wrote:</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><blockquote type="cite" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">We could just write<br><br>let x: P &amp; Q<br>instead of<br>let x: Any&lt;P, Q&gt;<br><br>let x: Collection where .Element: P<br>instead of<br>let x: Any&lt;Collection where .Element: P&gt;<br><br>let x: P &amp; Q where P.T == Q.T<br>instead of<br>let x: Any&lt;P, Q where P.T == Q.T&gt;<br><br>let x: P &amp; Q &amp; R<br>instead of<br>let x: Any&lt;P, Q, R&gt;<br><br>let x: Collection<br>instead of<br>let x: Any&lt;Collection&gt;<br><br><br>This would avoid the confusion of Any&lt;T1, T2&gt; being something completely<br>different than a generic type (i.e. order of T1, T2 does not matter whereas<br>for generic types it is essential).<br><br><br>-Thorsten<br><br><br><br><blockquote type="cite">Am 26.05.2016 um 20:11 schrieb Adrian Zubarev via swift-evolution<br>&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><span> </span>&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">mailto:swift-evolution@swift.org</a>&gt;&gt;:<br><br>Something like |type&lt;…&gt;| was considered at the very start of the whole<br>discussion (in this thread<br>&lt;<a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160502/016523.html" target="_blank">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160502/016523.html</a>&gt;),<br>but it does not solve the meaning of an existential type and also might<br>lead to even more confusion.<br><br>From my perspective I wouldn’t use parentheses here because it looks more<br>like an init without any label |Type.init(…)| or |Type(…)|. I could live<br>with |Any[…]| but this doesn’t look shiny and Swifty to me. Thats only my<br>personal view. ;)<br><br><br><br><br>--<br>Adrian Zubarev<br>Sent with Airmail<br><br>Am 26. Mai 2016 bei 19:48:04, Vladimir.S via swift-evolution<br>(<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><span> </span>&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">mailto:swift-evolution@swift.org</a>&gt;) schrieb:<br><br><blockquote type="cite">Don&#39;t think {} is better here, as they also have &quot;established meaning in<br>Swift today&quot;.<br><br>How about just Type(P1 &amp; P2 | P3) - as IMO we can think of such<br>construction as &quot;creation&quot; of new type and `P1 &amp; P2 | P3` could be treated<br>as parameters to initializer.<br><br>func f(t: Type(P1 &amp; P2 | P3)) {..}<br><br><br>On 26.05.2016 20:32, L. Mihalkovic via swift-evolution wrote:<br>&gt; How about something like Type{P1 &amp; P2 | P3} the point being that &quot;&lt;...&gt;&quot; has an established meaning in Swift today which is not what is expressed in the &quot;&lt;P1,P2,P3&gt;&quot; contained inside Any&lt;P1, P2,P3&gt;.<br>&gt;<br>&gt;&gt; On May 26, 2016, at 7:11 PM, Dave Abrahams via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><span> </span>&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">mailto:swift-evolution@swift.org</a>&gt;&gt; wrote:<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt;&gt; on Thu May 26 2016, Adrian Zubarev &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><span> </span>&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">mailto:swift-evolution@swift.org</a>&gt;&gt; wrote:<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; There is great feedback going on here. I&#39;d like to consider a few things here:<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; * What if we name the whole thing `Existential&lt;&gt;` to sort out all<br>&gt;&gt;&gt; confusion?<br>&gt;&gt;<br>&gt;&gt; Some of us believe that “existential” is way too theoretical a word to<br>&gt;&gt; force into the official lexicon of Swift. I think “Any&lt;...&gt;” is much<br>&gt;&gt; more conceptually accessible.<br>&gt;&gt;<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; This would allow `typealias Any = Existential&lt;&gt;`. * Should<br>&gt;&gt;&gt; `protocol A: Any&lt;class&gt;` replace `protocol A: class`? Or at least<br>&gt;&gt;&gt; deprecate it. * Do we need `typealias AnyClass = Any&lt;class&gt;` or do we<br>&gt;&gt;&gt; want to use any class requirement existential directly? If second, we<br>&gt;&gt;&gt; will need to allow direct existential usage on protocols (right now we<br>&gt;&gt;&gt; only can use typealiases as a worksround).<br>&gt;&gt;<br>&gt;&gt; --<br>&gt;&gt; Dave<br>&gt;&gt;<br>&gt;&gt; _______________________________________________<br>&gt;&gt; swift-evolution mailing list<br>&gt;&gt;<span> </span><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><span> </span>&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">mailto:swift-evolution@swift.org</a>&gt;<br>&gt;&gt;<span> </span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>&gt; _______________________________________________<br>&gt; swift-evolution mailing list<br>&gt;<span> </span><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><span> </span>&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">mailto:swift-evolution@swift.org</a>&gt;<br>&gt;<span> </span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>&gt;<br>_______________________________________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><span> </span>&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">mailto:swift-evolution@swift.org</a>&gt;<br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></blockquote><br>_______________________________________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><span> </span>&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">mailto:swift-evolution@swift.org</a>&gt;<br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></blockquote><br><br><br>_______________________________________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></blockquote></div></blockquote></div><br></div></div></div>_______________________________________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div></blockquote></div><br></div>_______________________________________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div></div></div></blockquote></div></div></blockquote></div><br></div></div></blockquote></div></div></div><br></div></blockquote></div><br></div></div>