Skip to content

Make sealed type hierarchies more pleasurable to use #3674

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
matanlurey opened this issue Mar 26, 2024 · 3 comments
Closed

Make sealed type hierarchies more pleasurable to use #3674

matanlurey opened this issue Mar 26, 2024 · 3 comments
Labels
feature Proposed language feature that solves one or more problems

Comments

@matanlurey
Copy link
Contributor

Some overlap with #336. Feel free to merge if useful.


Problem statement:

I wish I could nest classes and enums in particular. Relatively minor, but seems limiting compared to Kotlin, Swift.

I wish there was a shorthand syntax to easily create sealed type hierarchies. Sealed classes are great, but having to write 100+ lines to express what an enum can in ~10 is unfortunate.

A sealed-class hierarchy is awesome in Dart 3.x, but it's exceptionally more verbose and less API friendly than comparable languages (Rust, Swift, Kotlin). The verbosity here is not "number of key strokes" (which I don't think is the most important thing to focus on), but also public API surface.

Assume I have an API that takes a String and tries to parse it as an email address during account registration:

Email? tryParseEmail(String input) { /* ... */ }

Great! Later though, I decide I want to give the user actionable feedback, not just return null if the parse was invalid:

EmailResult parseEmail(String input) { /* ... */ }

sealed class EmailResult {}
final class SuccessfulEmailResult implements EmailResult {
  SuccessfulEmailResult(this.email);
  final Email email;
}
final class MissingDomainEmailResult implements EmailResult {
  MissingDomainEmailResult();
}
final class AlreadyTakenEmailResult implements EmailResult {
  AlreadyTakenEmailResult();
}
// You can imagine more possibilities, but stopping here for brevity.

Great, so I've now defined 4 classes, polluting my type hierarchy.

For another example, here is my Card hierarchy in another app

image


My wish:

I'd love to be able to define my hierarchy like this:

// This is a made up syntax.
sealed enum EmailResult {
  success(final Email email),
  missingDomain,
  alreadyTaken,
}

I could just use a plain enum and make email nullable, but that only works for this very simple example and breaks down very quickly for a more complex hierarchy.

Alternatively, and arguably more generally useful, I wish I could at least nest the classes:

// This is a made up syntax.
sealed enum EmailResult {
  final class Success implements EmailResult { /* ... */ }
  final class MissingDomain implements EmailResult { /* ... */ }
  final class AlreadyTaken implements EmailResult { /* ... */ }
}

With that last bit, I get:

  • Less API pollution
  • Shorter names that make more sense and are more discoverable
  • The ability for kick-ass switch expressions:
switch (result) {
  final EmailResult.Success _ => ...,
  final EmailResult.MissingDomain _ => ...,
  final EmailResult.AlreadyTaken _ => ...,
}

Perhaps if we ever get "implicit enum receivers" that could also be extended further:

switch (result) {
  final .Success _ => ...,
  final .MissingDomain _ => ...,
  final .AlreadyTaken _ => ...,
}
@matanlurey matanlurey added the feature Proposed language feature that solves one or more problems label Mar 26, 2024
@rubenferreira97
Copy link

This seems related to #3021 (if not a duplicate).

@munificent
Copy link
Member

munificent commented Mar 28, 2024

Yes, I would love some nicer notation for defining a sealed family of classes. As @rubenferreira97 says, #3021 is another issue discussing basically the same syntax. I'll close this one as a dupe of that. My comment on that issue still pretty much sums up my thoughts.

@munificent munificent closed this as not planned Won't fix, can't repro, duplicate, stale Mar 28, 2024
@matanlurey
Copy link
Contributor Author

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems
Projects
None yet
Development

No branches or pull requests

3 participants