<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Mon, Mar 13, 2017 at 6:38 AM Dimitri Racordon via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; 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" class="gmail_msg">
Hello swift-evolution,
<div class="gmail_msg"><br class="gmail_msg">
</div>
<div class="gmail_msg">I noticed there’s some inconsistencies with recursive types and how the compiler handles them. Consider the following cases:</div>
<div class="gmail_msg"><br class="gmail_msg">
</div>
<div class="gmail_msg"><br class="gmail_msg">
</div>
<div class="gmail_msg"><b class="gmail_msg">1. <span style="font-family:Menlo;font-size:11px;font-variant-ligatures:no-common-ligatures" class="gmail_msg"><span style="font-family:Helvetica;font-size:12px" class="gmail_msg">Swift is right to refuse compiling this, since there’s no way
 to initialise an instance of `</span>First<span style="font-family:Helvetica;font-size:12px" class="gmail_msg"> `:</span></span></b></div>
<div class="gmail_msg"><br class="gmail_msg">
</div>
<div class="gmail_msg">
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">struct</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> First {</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">    <span style="color:rgb(186,45,162);font-variant-ligatures:no-common-ligatures" class="gmail_msg">let</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> </span>item: </span>First</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">}</span></div>
</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<div style="margin:0px;line-height:normal;color:rgb(0,132,0)" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">// Error: Value type &#39;First&#39; cannot have a stored property that references itself</span></div>
</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<br class="gmail_msg">
</div>
<div style="margin:0px;line-height:normal" class="gmail_msg">However, the message suggests more a compiler limitation rather than the actual impossibility to initialize the declared type.</div>
<div style="margin:0px;line-height:normal" class="gmail_msg"><br class="gmail_msg">
</div>
<div style="margin:0px;line-height:normal" class="gmail_msg"><br class="gmail_msg">
</div>
<div style="margin:0px;line-height:normal" class="gmail_msg"><b class="gmail_msg">2. Swift is also right not to compile this, but the error messages are even less insightful:</b></div>
<div style="margin:0px;line-height:normal" class="gmail_msg"><br class="gmail_msg">
</div>
<div style="margin:0px;line-height:normal" class="gmail_msg">
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">struct</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> First {</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">let</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> item:
</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">Second</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">}</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><span style="color:rgb(0,132,0)" class="gmail_msg">// Error: Value type &#39;First&#39; cannot have a stored property that references itself</span></span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><br class="gmail_msg">
</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"></span><br class="gmail_msg">
</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">struct</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> Second {</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">let</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> item:
</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">First</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">}</span></div>
<div style="margin:0px;line-height:normal" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><font color="#008400" face="Menlo" class="gmail_msg"><span style="font-size:11px" class="gmail_msg">// Error: Value type </span></font><span style="color:rgb(0,132,0);font-family:Menlo;font-size:11px" class="gmail_msg">&#39;</span><font color="#008400" face="Menlo" class="gmail_msg"><span style="font-size:11px" class="gmail_msg">Second&#39;
 cannot have a stored property that references itself</span></font></span></div>
<div class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><br class="gmail_msg">
</span></div>
</div>
<div style="margin:0px;line-height:normal" class="gmail_msg">The problem isn’t that the value types reference
<i class="gmail_msg">themselves</i>. Instead, the problem is that there’s a cyclic dependency between `First` and `Second` that makes it impossible for neither of these structures to be instantiated.</div>
<div style="margin:0px;line-height:normal" class="gmail_msg"><br class="gmail_msg">
</div>
<div style="margin:0px;line-height:normal" class="gmail_msg"><br class="gmail_msg">
</div>
<div style="margin:0px;line-height:normal" class="gmail_msg"><b class="gmail_msg">3. Swift should let me do that:</b></div>
<div style="margin:0px;line-height:normal" class="gmail_msg"><br class="gmail_msg">
</div>
<div style="margin:0px;line-height:normal" class="gmail_msg">
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">struct</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> First {</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">let</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> item:
</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">First</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">?</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">}</span></div>
<div class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><br class="gmail_msg">
</span></div>
<div class="gmail_msg">The compiler prevents me to declare the above struct, even if there actually is a way to initialise an instance of `First` (e.g. `First(item: nil)`). The message is identical to that of case #1 (maybe it actually
<i class="gmail_msg">is</i> a compiler limitation after all?)</div></div></div></blockquote><div><br></div><div>The problem with this example is that since Optional&lt;T&gt; is a value type (an enum), this is a value type that is recursive upon itself. Until indirect struct fields are possible, this can&#39;t be supported—there&#39;s *one* valid way to instantiate it without recursion at runtime, but the compiler can&#39;t know what you might try to pass in there, nor can it (I believe) compute the layout of that type because of the potential recursion.</div><div><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" class="gmail_msg"><div style="margin:0px;line-height:normal" class="gmail_msg">
<div class="gmail_msg"><br class="gmail_msg">
</div>
<div class="gmail_msg"><br class="gmail_msg">
</div>
<div class="gmail_msg"><b class="gmail_msg">4. Swift shouldn’t compile this:</b></div>
<div class="gmail_msg"><br class="gmail_msg">
</div>
<div class="gmail_msg">
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">class</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> First {</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">let</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> item:
</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">First</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">init</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">(item:
</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">First</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">) {</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">        </span>
<span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">self</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">.</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">item</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">
 = item</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">    }</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">}</span></div>
</div>
<div class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><br class="gmail_msg">
</span></div>
<div class="gmail_msg">Like in case #1, there’s no way to instantiate `First`. The fact that it’s a reference rather than a value doesn’t change the problem.</div>
<div class="gmail_msg"><br class="gmail_msg">
</div>
<div class="gmail_msg"><br class="gmail_msg">
</div>
<div class="gmail_msg"><b class="gmail_msg">5. Similarly to case #4, Swift shouldn’t compile this:</b></div>
<div class="gmail_msg"><br class="gmail_msg">
</div>
<div class="gmail_msg">
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(186,45,162)" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">indirect</span><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg">
</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">enum</span><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg"> First {</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">case</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> item(</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">First</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">)</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg">
<span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">}</span></div>
</div>
<div class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><br class="gmail_msg"></span></div></div></div></blockquote><div><br></div><div>Re: #4 and #5, I&#39;ve been pondering the same thing lately because I&#39;ve been tinkering with an implementation of auto-deriving Equatable/Hashable for enums in my spare time, and I&#39;ve been using recursive cases like this to test edge cases. For something like #5, I can generate the bodies of == and hashValue, but what good are they for a type that you can&#39;t actually get values of?</div><div><br></div><div>In general, having noninstantiable types is good—caseless enums are useful as a way of namespacing static members. But in the specific case where a type is impossible to instantiate because of infinite recursion, a compiler diagnostic sounds like a good idea. I&#39;m trying to think of situations where that would be valid and someone would need that functionality, but I&#39;m coming up blank. But, I&#39;m no expert on type systems.</div><div><br></div><div><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" class="gmail_msg"><div style="margin:0px;line-height:normal" class="gmail_msg"><div class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">
</span></div>
<div class="gmail_msg"><br class="gmail_msg">
</div>
<div class="gmail_msg"><b class="gmail_msg">6. Cases #4 #5 could be written like case #2, and should also raise compilation errors.</b></div>
<div class="gmail_msg"><br class="gmail_msg">
</div>
<div class="gmail_msg"><br class="gmail_msg">
</div>
<div class="gmail_msg">Does someone know if these issues have already been discussed and/or addressed?</div>
<div class="gmail_msg"><br class="gmail_msg">
</div>
<div class="gmail_msg">Thanks,</div>
<div class="gmail_msg">Dimitri Racordon</div>
<div class="gmail_msg"><br class="gmail_msg">
</div>
</div>
</div>

_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div></div>