<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br><br>Sent from my iPad</div><div><br>On Sep 17, 2017, at 5:02 PM, Jonathan Hull <<a href="mailto:jhull@gbis.com">jhull@gbis.com</a>> wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><br class=""><div><blockquote type="cite" class=""><div class="">On Sep 17, 2017, at 7:55 AM, Matthew Johnson <<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""><br class="">Sent from my iPad</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class="">On Sep 17, 2017, at 3:37 AM, Jonathan Hull via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class=""><div class="">I run into use cases like this all the time…<div class=""><br class=""></div><div class="">I think I would prefer to see those concrete cases in a subtype though:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>enum DrinkSize {</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>case small</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>case medium</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>case large</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>enum SummerDrinkSize : DrinkSize {</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>//Inherits DrinkSize’s cases</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>case extraLarge</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}</div><div class=""><br class=""></div><div class="">Because it is a subtype, you could place a SummerDrinkSize anywhere you can put a DrinkSize. As a result, all switches on it would need a default case to handle cases they hadn’t planned for. If you mark an enum with “<b class="">final</b>” then it can’t be extended and switches can be exhaustive.</div></div></blockquote><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">You have the subtype relationship backwards here. DrinkSize is a subtype of SummerDrinkSize. All values of DrinkSize are also valid values of SummerDrinkSize but not vice versa. For this reason, inheritance syntax doesn't make sense. The syntax that makes more sense is some kind of case embedding syntax:</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">enum SummerDrinkSize {</span></font></div><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>cases DrinkSize</span></font></div><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>case extraLarge</span></font></div><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">}</span></font></div></div></div></blockquote><div><br class=""></div><div>I disagree. I get that the shape of a DrinkSize would always fit in a SummerDrinkSize hole (ignoring the overriding/extension of methods), but the fact that we are requiring ‘default’ in switches changes the calculus. Basically, it changed when we decided to change whether exhaustive was the default. The point is to make people consider that they may have cases which they may not expect. That is much easier with a concrete idea of subtype, which people are already used to.</div></div></div></blockquote><div><br></div><div>Requiring developers to consider cases that may be added to an enum in the future is orthogonal to any potential subtype relationship between two value types.</div><br><blockquote type="cite"><div><div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class=""><div class=""><div class=""><br class=""></div><div class="">In addition to inheriting the cases, a subtype would also inherit, and be able to override, methods defined on the super-type. You could use super to call the super-type’s implementation. </div></div></blockquote><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">I think implementation sharing is a bad idea for value types. Value subtyping should be conceptualized as a restricted mechanism for value-preserving implicit conversion.</div></div></blockquote><div><br class=""></div><div>Why?</div></div></div></blockquote><div><br></div><div>First, this is how value subtyping already works in the case of Optional where `T` is a subtype of `T?`.</div><div><br></div><div>More generally, this approach is roughly analogous to implicit promotion in C-family languages. We want `Int8` to be a subtype of `Int16`, `Int32`, `Int`, etc.</div><div><br></div><div>This approach allows a value type to have multiple value-preserving supertypes without the performance impact of dynamic dispatch or the complexity of multiple inheritance.</div><br><blockquote type="cite"><div><br class=""><div class=""><br class=""></div></div></blockquote></body></html>