<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 <<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" 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 'First' 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 'First' 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">'</span><font color="#008400" face="Menlo" class="gmail_msg"><span style="font-size:11px" class="gmail_msg">Second'
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<T> is a value type (an enum), this is a value type that is recursive upon itself. Until indirect struct fields are possible, this can't be supported—there's *one* valid way to instantiate it without recursion at runtime, but the compiler can'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've been pondering the same thing lately because I've been tinkering with an implementation of auto-deriving Equatable/Hashable for enums in my spare time, and I'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'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'm trying to think of situations where that would be valid and someone would need that functionality, but I'm coming up blank. But, I'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>