<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class=""><br class=""></div><div><blockquote type="cite" class=""><div class="">On Mar 21, 2016, at 7:58 AM, Tino Heth via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Many languages which adopt the concept of value types don't allow subclassing for those, and so does Swift.</div><div class="">Inheritance for structs is more complex than inheritance for classes, but the "final" limitation isn't the only possible solution, and Dave Abrahams told me in another thread that changing this rule might be considered in the future — so I'll risk getting taunted by the cool kids who are in favor of eliminating all ancient OOP-ideas ;-) and start a discussion.</div><div class=""><br class=""></div><div class="">I guess most readers know about the low-level problems that arise when we switch from pointers (always the same size) to value types (size may vary), so I'll start with two possibilities for struct subtyping:</div><div class=""><br class=""></div><div class=""><u style="font-size: 14px;" class="">newtype</u> (see&nbsp;<a href="https://www.haskell.org/tutorial/moretypes.html" class="">https://www.haskell.org/tutorial/moretypes.html</a>&nbsp;— or just read on if you are scared by Haskell ;-)</div><div class=""><br class=""></div><div class="">When a subtype does not add any stored properties to its superclass (memory layout doesn't change), there is no difference at the level of object code — only the type checker may stop you from using those two types interchangeably.</div></div></div></blockquote><div><br class=""></div><div><div class="">As I understand it, a single argument struct ends up being as “free” as a newtype is in Haskell (modulo resiliency concerns), or close to it. For instance, my understanding is that the Int type is a single argument struct wrapper around a lower-level numeric type.</div></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Some use cases:</div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">- In Cocoa, there is no separate class for (file system) paths; instead, there are some additions to NSString. String doesn't have those abilities, and imho methods like "<span style="color: rgb(61, 29, 129); font-family: Menlo; font-size: 11px;" class="">stringByAppendingPathExtension"&nbsp;</span>deserve a separate Path-struct, so that those special methods don't pollute the method list of String (URL is the future, so that example is somewhat out-of date).</div><div class="">- You could impose incompatibility on numeric types to ensure that your calculations use correct quantities. Although this can be annoying (Float vs. CGFloat), decorating numbers with quantity/unit could eliminate bugs that had really disastrous consequences in the past.</div><div class="">- Increased comfort for floating-point math:</div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">struct</span> CustomDouble: Double</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="" class=""> == (a: </span>CustomDouble<span style="" class="">, b: </span>CustomDouble<span style="" class="">) -&gt; </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span><span style="" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">abs</span>(a.<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">value</span> - b.<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">value</span>) &lt; <span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">0.01</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div><div class="">(no need to specify tolerance for each comparison)</div><div class=""><br class=""></div><div class=""><span style="font-size: 14px;" class=""><u class="">Full subtyping</u></span></div><div class=""><br class=""></div><div class="">As long as you don't cross module borders, it wouldn't be that complicated to add inheritance without restrictions.</div><div class="">imagine you have a "Customer"-type and a "Employee"-type to store personal data (name, address…).</div><div class="">Those data objects are perfect candidates to be implemented as structs, but they also cry for a "Person"-superclass, so you are forced to either duplicate code, or to implement your objects as reference types.</div></div></div></blockquote><br class=""></div><div>There’s a number of wrinkles that are worth considering—for instance, are you doing nominal or structural subtyping? The value-nature of structs suggests that structural subtyping would be useul. However, structs are already nominal types (unlike tuples).</div><div><br class=""></div><div>Some compelling use cases for why a class doesn’t suffice and you really need a struct would enhance a full proposal.</div><div><br class=""></div><div>Cheers,</div><div>-Colin</div><div><br class=""></div><br class=""></body></html>