> On Mar 21, 2016, at 7:58 AM, Tino Heth via swift-evolution 
> <[email protected]> wrote:
> 
> Many languages which adopt the concept of value types don't allow subclassing 
> for those, and so does Swift.
> 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.
> 
> 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:
> 
> newtype (see https://www.haskell.org/tutorial/moretypes.html 
> <https://www.haskell.org/tutorial/moretypes.html> — or just read on if you 
> are scared by Haskell ;-)
> 
> 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.

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.

> Some use cases:
> - 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 "stringByAppendingPathExtension" 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).
> - 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.
> - Increased comfort for floating-point math:
> struct CustomDouble: Double
> 
> func == (a: CustomDouble, b: CustomDouble) -> Bool {
>       return abs(a.value - b.value) < 0.01
> }
> (no need to specify tolerance for each comparison)
> 
> Full subtyping
> 
> As long as you don't cross module borders, it wouldn't be that complicated to 
> add inheritance without restrictions.
> imagine you have a "Customer"-type and a "Employee"-type to store personal 
> data (name, address…).
> 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.

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).

Some compelling use cases for why a class doesn’t suffice and you really need a 
struct would enhance a full proposal.

Cheers,
-Colin


_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to