3 ms·
Does it (Dart, C#) support exhaustivity checking for such matching over subclasses?
by andreypopp 3y ago
Does it (Dart, C#) support exhaustivity checking for such matching over subclasses?
- zengid 3y agoNot sure about Dart, but for C# I don't think it can (due to classes being open by default). If anyone is interested in a deeper dive on C# and adding Discriminated Unions, this interview by Nick Chapsas with Mads Torgersen is a great discussion: https://youtu.be/Nuw3afaXLUc?t=3939 https://youtu.be/Nuw3afaXLUc?t=3939 (note, I'm pretty sure this time stamp is the right part, but the discussion might start before this. I'm at work and can't listen too closely to the video atm).
- zengid 3y agoAfter re-watching, exhaustiveness is not a feature yet. If you look above to munificent's comment, you'll see that Dart has it! very cool!
- munificent 3y agoI don't know about C#, but, yes Dart has quite sophisticated exhaustiveness checking over sealed class hiearchies, including hierarchies that are DAGs and not just trees. It also handles record/tuple types and generics, nested arbitrarily deeply. And patterns that call arbitrary getters on objects. For example, if you have this class hierarchy: sealed class A {} sealed class B1 implements A {} sealed class B2 implements A {} class C1 implements B1 {} class C2 implements B1, B2 {} class C3 implements B2 {} // A // / \ // B1 B2 // / \ / \ // C1 C2 C3 Then it understands that this switch statement is exhaustive: void test(A a1, A a2) { switch ((a1, a2)) { case (A(), C1()): print(1); case (C2(), C2()): print(2); case (C3(), B2()): print(3); case (B1(), B2()): print(4); } } Because they cover the Cartesian product of all possible combinations of subtypes like: a1 A / \ B1 B2 / \ / \ C1 C2 C3 a2 +----+----+----+ C1| 1 | B1< +----+----+----+ A< C2| | 2 | | B2< + +----+ 3 + C3| 4 | | +----+----+----+ This can extend to arbitrary dimensions based on how many record fields there are. Figuring that all out was quite the challenge! The full design is here: https://github.com/dart-lang/language/blob/main/accepted/3.0/patterns/exhaustiveness.md https://github.com/dart-lang/language/blob/main/accepted/3.0...
- zengid 3y agoBravo! This is awesome.
- tomcam 3y agothanks tons for that amazing comment. Helped me tremendously. Illustrations are incredibly helpful in cases like this.
- munificent 3y agoYou're welcome. The real challenge is that pictures like this only work for simple two-element tuples. Once you have more fields in the tuple, or nested destructuring, the manifold of the value space the patterns have to cover quickly gets into higher dimensions that are basically impossible to visualize.
- tomcam 3y agoYeah but you helped me over the initial hump. Much easier to get to the more involved cases now.
- jjtheblunt 3y agohttps://dart.dev/language/class-modifiers-for-apis#the-sealed-modifer https://dart.dev/language/class-modifiers-for-apis#the-seale... that first paragraph, i believe, addresses your question, with excellent example from munificent in sibling comment.
- randyrand 3y agoyes, you declare your class 'sealed' (introduced in Dart 3.0)