3 ms·
I can understand the intent behind most of the design 'no's - except for subtyping. why is this a problem? I was just looking at the union/sum distinction and t
by convolvatron 3y ago
I can understand the intent behind most of the design 'no's - except for subtyping. why is this a problem? I was just looking at the union/sum distinction and the same thing came up. maybe this is a good learning moment.
- Joker_vD 3y agoWell, the language has no implicit type conversions so there is no much point in having subtyping either. On the other hand, subtyping interacts very, very badly with both type inference (it almost instantly becomes undecideable, in practice as well as in theory) and with typeclasses (again, decidability issues).
- dataangel 3y agoPL designers like to cast features that make their job harder and user's life easier as "anti-features"
- otabdeveloper4 3y agoThis.
- mamcx 3y ago> No subtyping. Adding it open a can of worms. Your type-inference/checking must account for "similar but..." types, you need to follow hierarchies/graphs/trees,etc, you need a way to "re-import" code that "belongs to the super type" (and probably recheck it?), it not always mesh well with other features (or make it harder). Aside: One of the big reasons to make a bit list of "NO" is to avoid the temptation of "add some sugar to make this easier" but without fully understanding the consequences until becomes later.
- hansvm 3y agoType systems invariably have soundness issues when subtyping is allowed. They might've fixed it in the last couple years, but as an example I'm pretty sure Java and C# both have bugs where some methods should be co/contra-variant and others should not but the language only supports subtyping acting one way or the other for the whole type. For a concrete example: 1. Suppose Civic is a subtype of Car 2. Suppose you have a List<Civic> 3. Suppose a method asks for a List<Car> 4. You can "clearly" provide that original list of civics because every single thing in the list is a Car, and it's a list of those things, so it adheres to what the method seems to want -- maybe the method computes average cylinder count or something. 5. Everything we just described is fine and dandy so long as the list itself is immutable (the individual cars could still be mutable safely), but running some of the mutable list methods will cause runtime crashes and segfaults. E.g., if you append a toyota camry to the list then you've somehow snuck a camry into the original List<Civic>. In that example, some of the methods would be safe if you interpreted a List<Civic> as a List<Car> (like grabbing the car at a particular index and finding that the particular car is a civic), but others require the subtyping relationship to go the other direction (e.g., if you interpreted the List<Civic> as a List<BlueCivic> and appended a BlueCivic then the invariants expected by `append` work in both cases). That sort of thing just scratches the tip of the iceberg, and as a rule of thumb all your type systems are unsound, _especially_ if they involve subtyping. Things you would hope would be caught at compile-time are punted off to scary runtime heisenbugs that might not be detected for ages. The type system is helpful at reducing errors but woefully incomplete even for the things it's supposed to catch.