Skip to content
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

Alternative type naming for sealed class subclasses #4166

Closed
nathnaeld opened this issue Nov 20, 2024 · 4 comments
Closed

Alternative type naming for sealed class subclasses #4166

nathnaeld opened this issue Nov 20, 2024 · 4 comments
Labels
feature Proposed language feature that solves one or more problems

Comments

@nathnaeld
Copy link

nathnaeld commented Nov 20, 2024

Current Behavior

To maintain clarity, long class names may be used explicitly in the absence of an alternative short naming mechanism.

sealed class Animal {}
class WildAnimal extends Animal {}
class DomesticAnimal extends Animal {}
class AquaticAnimal extends Animal {}
class FlyingAnimal extends Animal {}

Animal someOperation() {
  final int result = apiCall();

  if (result == 1) {
    return WildAnimal();
  } else if (result == 2) {
    return AquaticAnimal();
  } else if (result == 3) {
    return FlyingAnimal();
  } else {
    return DomesticAnimal();
  }
}

void main() {
  final animal = someOperation();

  switch (animal) {
    case WildAnimal:
      print('The animal is wild.');
    case DomesticAnimal:
      print('The animal is domestic.');
    case AquaticAnimal:
      print('The animal is aquatic.');
    case FlyingAnimal:
      print('The animal is flying.');
  }
}

Proposed Feature

Introduce an alternative naming mechanism for sealed class subclasses, allowing shorter, more intuitive names while retaining the original functionality.

sealed class Animal {}

// Alternative 1
class WildAnimal extends Animal alias Wild {}
class DomesticAnimal extends Animal alias Domestic {}
class AquaticAnimal extends Animal alias Aquatic {}
class FlyingAnimal extends Animal alias Flying {}

// Alternative 2
class WildAnimal as Wild extends Animal  {}
class DomesticAnimal as Domestic extends Animal  {}
class AquaticAnimal as Aquatic extends Animal {}
class FlyingAnimal as Flying extends Animal {}

// Alternative 3
class WildAnimal, Wild extends Animal  {}
class DomesticAnimal, Domestic extends Animal  {}
class AquaticAnimal, Aquatic extends Animal {}
class FlyingAnimal, Flying extends Animal {}

Animal someOperation() {
  final int result = apiCall();

  if (result == 1 ) {
    return Animal.Wild();
  } else if (result == 2) {
    return Animal.Aquatic();
  } else if (result == 3) {
    return Animal.Flying();
  } else {
    return Animal.Domestic();
  }
}

void main() {
  final Animal animal = someOperation();

  switch (animal) {
    case Wild:
      print('The animal is wild.');
    case Domestic:
      print('The animal is domestic.');
    case Aquatic:
      print('The animal is aquatic.');
    case Flying:
      print('The animal is flying.');
  }
}

Benefits

  1. Improved Readability: Short alternative names like Wild, Domestic, Aquatic, and Flying reduce verbosity and improve code clarity. They also simplify switch statements by eliminating long case names, making the code more concise, easier to read, and maintain without sacrificing clarity.
  2. Scoped Names: Alternative names are scoped within the sealed class, avoiding naming conflicts.
  3. Developer Convenience: Subclasses can be accessed using concise, memorable aliases (e.g., Animal.Wild), eliminating the need to recall full class names or the inheritance structure, leading to more efficient and less error-prone code.

This feature is a quality-of-life improvement that is fully backward-compatible, offering ergonomic enhancements when working with sealed classes, particularly in state management scenarios like Flutter Bloc or other hierarchical structures.

@nathnaeld nathnaeld added the feature Proposed language feature that solves one or more problems label Nov 20, 2024
@nathnaeld nathnaeld changed the title Alternative name and call for sealed class subclasses Alternative type naming for sealed class subclasses Nov 20, 2024
@mateusfccp
Copy link
Contributor

mateusfccp commented Nov 20, 2024

Could be solved with #336.

@lrhn
Copy link
Member

lrhn commented Nov 20, 2024

Agree. I'd rather have real static nested classes than any aliasing or shorthand.
Combined with "enum shorthand" (#1183), I could see

sealed class Animal {
  static class Wild extends Animal { ... }
  static class Domestic extends Animal { ... }
  ///
}

also allow

switch (someAnimal) {
  case .Wild(...): ...
  case .Domestic(...): ...
  ...
}

@mraleph
Copy link
Member

mraleph commented Nov 22, 2024

Also somewhat related to #3021

@munificent
Copy link
Member

munificent commented Nov 26, 2024

I agree with @nathnaeld that not having to effectively namespace the sealed classes with their supertype name would be nice. But as @lrhn says, I think the best way to get that is through some kind of nested class support like #1183 or #3021.

I'm going to go ahead and close this because I don't think this is the specific approach we're likely to take.

@munificent munificent closed this as not planned Won't fix, can't repro, duplicate, stale Nov 26, 2024
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

5 participants