<div dir="ltr">What's the behavior if you have something like this:<div><br></div><div>struct Foo<T, U> {</div><div> func foo(bar: Any<T, U>) { ... }</div><div>}</div><div>let f = Foo<A, A></div><div><br></div><div>...?</div><div><br></div><div>More generally, my fear is that being *too* restrictive about banning redundant types could get you into a situation through generic metaprogramming where you might *want* that argument to coalesce to just "A", but if the redundancy check is implemented a certain way, you've just prevented a perhaps legitimate usage with no easy workaround.</div><div><br></div><div>I'm inclined to just say: minimize redundant types automatically and if a user wants to write something redundant, that's fine—so a variable declared with type `Any<A, A>` would actually be of type `A`. <span style="line-height:1.5">You might be able to avoid this if you only check the *literal* type or type parameter name going into the Any<>, but I'm not sure how much difficulty that is on the type checking side, and then you'd only catch some of the cases and you'd still have to be able to minimize.</span></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Fri, May 20, 2016 at 7:53 AM Adrian Zubarev via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br></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 style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">What I meant here is, that the example should produce an error because it is basically `Any<Any<Any<…>>>` which should be banned. It depends on the context. Using typealias in general can be allowed but it depends how you will use and nest it.</div><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">This example is valid:</div><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">protocol A {} protocol B {} protocol C {}</div><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">typealias AB = Any<A, B></div><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">typealias ABC = Any<AB, C></div><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">If we ban `Any<Any<...>>` one should not abuse `typealias` to achieve that, even if its useless. I’m not sure how hard that would be implement that restriction.</div><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">The example you was pointing at wouldn’t work anyway because the rule #3 and rule #4 should raise an error. Thats how I see it.</div><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto"><br></div><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">If I’m not correct please provide an example that makes more sense. :)</div></div><div style="word-wrap:break-word"> <br> <div><div style="font-family:helvetica,arial;font-size:13px">-- <br>Adrian Zubarev<br>Sent with Airmail</div></div> <br></div><div style="word-wrap:break-word"><p>Am 20. Mai 2016 bei 16:44:35, Matthew Johnson (<a href="mailto:matthew@anandabits.com" target="_blank">matthew@anandabits.com</a>) schrieb:</p> <blockquote type="cite"><span><div dir="auto"><div></div><div>
<div><br>
<br>
Sent from my iPad</div></div></div></span></blockquote></div><div style="word-wrap:break-word"><blockquote type="cite"><span><div dir="auto"><div>
<div><br>
On May 20, 2016, at 4:39 AM, Adrian Zubarev via swift-evolution
<<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>>
wrote:<br>
<br></div>
<blockquote type="cite">
<div>
<div></div>
<div>
<div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">
This is a follow up proposal to <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md" target="_blank"><span style="color:rgb(0,0,0)">SE-0095</span></a> which
should be considered for Swift 3 if SE-0095 will be accepted.</div>
<div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">
<br></div>
<div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">
Here is the formatted draft: <a href="https://github.com/DevAndArtist/swift-evolution/blob/master/proposals/nnnn-ban-redundancy-in-any-existential.md" target="_blank">
https://github.com/DevAndArtist/swift-evolution/blob/master/proposals/nnnn-ban-redundancy-in-any-existential.md</a></div>
<div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">
<br></div>
<div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">
Please provide your feedback in this thread, and don’t make a race
who is making a better proposal on the exact same topic.</div>
<div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">
<br></div>
<div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">
If you spot any types or other mistakes I’d be happy to see you
pointing me to them. ;)</div>
<div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">
<br></div>
<div>
<div style="font-family:helvetica,arial;font-size:13px">
-- <br>
Adrian Zubarev<br>
Sent with Airmail</div>
</div>
</div>
<div>
<h1>Disallow redundant
<code>Any<...></code> constructs</h1>
<ul>
<li>Proposal: <a href="https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md" target="_blank">
SE-NNNN</a></li>
<li>Author: <a href="https://github.com/DevAndArtist" target="_blank">Adrian
Zubarev</a></li>
<li>Status: <a href="#m_-6273636555714890771_rationale">Awaiting review</a></li>
<li>Review manager: TBD</li>
</ul>
<h2>Introduction</h2>
<p>This is a follow up proposal to <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md" target="_blank">
SE–0095</a>, if it will be accepted for Swift 3. The current
concept of <code>Any<...></code> introduced in SE–0095 will
allow creation of redundant types like <code>Any<A> ==
A</code>. I propose to disallow such redundancy in Swift 3 to
prevent breaking changes in a future version of Swift.</p>
<p>Swift-evolution thread: <a>[Proposal] Disallow redundant
<code>Any<...></code> constructs</a></p>
<h2>Motivation</h2>
<p>If SE–0095 will be accepted there will be future proposals to
enhance its capabilities. Two of these will be <strong>Any-type
requirement</strong> (where <em>type</em> could be
<code>class</code>, <code>struct</code> or <code>enum</code>) and
<strong>Class requirement</strong>. Without any restrictions these
will introduce more redundancy.</p>
<p>As said before it is possible to create redundant types like
<code>Any<A> == A</code> or endless shadowed redundant
nesting:</p>
<pre><code>typealias A_1 = Any<A>
typealias A_2 = Any<A_1>
typealias A_3 = Any<A_2>
/* and so on */
</code>
</pre>
<p>This proposal should ban redundancy right from the beginning. If
there might be any desire to relax a few things, it won’t introduce
any breaking changes for <code>Any<...></code>
existential.</p>
</div>
</div>
</blockquote>
</div></div></span></blockquote></div><div style="word-wrap:break-word"><blockquote type="cite"><span><div dir="auto"><div><div>Why do you think having multiple typealiases for the same type
is a problem? The whole point of typealias is to
<b>alias</b> the name of the type. </div></div></div></span></blockquote></div><div style="word-wrap:break-word"><blockquote type="cite"><span><div dir="auto"><div>
<div><br></div>
<br>
<blockquote type="cite">
<div>
<div>
<h2>Proposed solution</h2>
<ol>
<li>
<p>If empty <code>Any<></code> won’t be disallowed in
SE–0095, we should disallow nesting empty <code>Any<></code>
inside of <code>Any<...></code>.</p>
</li>
<li>
<p>Disallow nesting <code>Any</code> (type refers to current
<code>typealias Any = protocol<></code>) inside of
<code>Any<...></code>.</p>
</li>
<li>
<p>Disallow <code>Any<...></code> containing a single
<code>Type</code> like <code>Any<Type></code>.</p>
<p>The first three rules will ban constructs like
<code>Any<Any<>, Type></code> or <code>Any<Any,
Type></code> and force the developer to use <code>Type</code>
instead.</p>
</li>
<li>Disallow nesting a single <code>Any<...></code> inside
another <code>Any<...></code>.
<ul>
<li>e.g. <code>Any<Any<FirstType,
SecondType>></code></li>
</ul>
</li>
<li>
<p>Disallow same type usage like <code>Any<A, A></code> or
<code>Any<A, B, A></code> and force the developer to use
<code>A</code> or <code>Any<A, B></code> if <code>A</code>
and <code>B</code> are distinct.</p>
</li>
<li>
<p>Disallow forming redundant types when the provided constraints
are not independent.</p>
<pre><code>// Right now `type` can only be `protocol` but in the future Any<...>
// could also allow `class`, `struct` and `enum`.
// In this example `B` and `C` are distinct.
type A: B, C {}
// all following types are equivalent to `A`
Any<A, Any<B, C>>
Any<Any<A, B>, C>
Any<Any<A, C>, B>
Any<A, B, C>
Any<A, B>
Any<A, C>
</code>
</pre>
<ul>
<li>
<p>If all contraints form a known <code>Type</code> provide a
<code>Fix-it</code> error depending on the current context. If
there is more than one <code>Type</code>, provide all alternatives
to the developer.</p>
</li>
<li>
<p>Using <code>Any<...></code> in a generic context might not
produce a <code>Fix-it</code> error:</p>
<pre><code>protocol A {}
protocol B {}
protocol C: A, B {}
// there is no need for `Fix-it` in such a context
func foo<T: Any<A, B>>(value: T) {}
</code>
</pre></li>
</ul>
</li>
</ol>
<h2>Impact on existing code</h2>
<p>These changes will break existing code. Projects abusing
<code>Any<...></code> to create redundant types should be
reconsidered of usings the equivalent <code>Type</code> the
compiler would infer. One would be forced to use <code>A</code>
instead of <code>Any<A></code> for example. A
<code>Fix-it</code> error message can help the developer to migrate
his project.</p>
<h2>Alternatives considered</h2>
<ul>
<li>Leave redundancy as-is for Swift 3 and live with it.</li>
<li>Deprecate redundancy in a future version of Swift, which will
introduce breaking changes.</li>
</ul>
</div>
</div>
</blockquote>
<blockquote type="cite">
<div>
<span>_______________________________________________</span><br>
<span>swift-evolution mailing list</span><br>
<span><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a></span><br>
<span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br>
</div>
</blockquote>
</div></div></span></blockquote></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" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div>