extension enum
When I need a set options(typically for switch), no run-time type check required, enum in dart is an over-kill, I would use extension type and static const variables instead.
Just like using the same syntax in a class, it is verbose, therefore I expect a feature similar to enum as extension type. Though not having it would be fine, having it would be great.
This is how it would look like right now
extension type const SudoEnum(int i){
static const option1 = SudoEnum(1);
static const option2 = SudoEnum(2);
static const option3 = SudoEnum(3);
}
And this is what I expect it to be
//For the constructor representing underlying structure,
//extension enum is always const,
//I think const keyword should be omitted.
extension enum SudoEnum(int i){
option1(1), option2(2), option3(3);
}
With primary constructors you can write
enum SudoEnum(int i) { option1(1), option2(2), option3(3) }
EDIT: for reference see #2364.
With primary constructors you can write
enum SudoEnum(int i) { option1(1), option2(2), option3(3) }EDIT: for reference see #2364.
Maybe I am strange, but I somehow care about creating an extra class, and that is why I use extension types.
Nothing prevents you from doing 4 as SudoEnum, so the enum isn't closed. Which means it's not an enum.
Trying to prevent that cast won't work, there'll always be a way, as long as it's an extension type.
And to be clear: You are strange. So am I. I completely get not wanting ... well, not the class, but the instance of the class.
The language just doesn't support that. The things you want from an enum are things that are inherently based on controlling identity of the values, and extension types delegate the identity, and control of instance creation, to the representation type.
The feature you want is not in the extension type feature.
And to be clear: You are strange. So am I. I completely get not wanting ... well, not the class, but the instance of the class.
The language just doesn't support that. The things you want from an enum are things that are inherently based on controlling identity of the values, and extension types delegate the identity, and control of instance creation, to the representation type.
The feature you want is not in the extension type feature.
The thing I want is just some integer that cannot be miswritten in code in wrong place.
The function or variable should not use the wrong integer, and the integer sould not be used in wrong way, so use extension type.
But simply creating a value manually everywhere is definitely a bad idea since I can remember or mistyped wrong value, so they should be predeclared in right scope with a readable name with meaning.
Declaring those integer is wordy. Enum looks simple, but why should I create a runtime class that exist just for a simple option?
I am just finding some easier way to declare all these static const.
As a convenience and help from the type system in not using incorrect values, an extension type with a fixed set of constants will work perfectly fine. It doesn't give the closure guarantees of an enum, which is why an extension enum type won't be a language feature. It wouldn't provide the other things an enum does, like exhaustiveness.
But the enum value syntax is awesome. Maybe we could consider allowing any class-like type declaration to declare constants. Maybe
extension type Foo(Bar _) {
enum foo1(bar1), foo2(bar2);
}
It'll just be shorthand for static const foo1 = Foo(bar1); and ...2...2....
Could be used in plain classes and mixins too.
But the enum value syntax is awesome. Maybe we could consider allowing any class-like type declaration to declare constants. Maybe
extension type Foo(Bar _) { enum foo1(bar1), foo2(bar2); }It'll just be shorthand for
static const foo1 = Foo(bar1);and...2...2....Could be used in plain classes and mixins too.
It's an interesting idea, but I think using the enum keyword would be confusing if you also eventually allow static nested enums/classes/mixins/etc. Also I don't think the feature would work with mixins since mixins don't have constructors, could also rule out abstract and sealed classes also since you can't instantiate those either.
But if there was such a feature, I would expect there to be no keyword, just a requirement that it come before any other member (same restriction enums currently have), and that it can only be used with const constructors.
extension type const Foo(Bar _) {
foo1(bar1), foo2(bar2); // must come before other members and
// only allowed with const constructors
}
Alternatively, foo1(bar1) could be shorthand for foo1 = Foo(bar1), and can be used with current keywords used to declare variables:
extension type const Foo(Bar _) {
static const foo1(bar1), foo2(bar2);
// static const foo1 = Foo(bar1), foo2 = Foo(bar2);
}
class Baz {
Baz(this.x, this.y);
Baz.named(this.x, this.y);
int x, y;
static Baz a(1, 2), b.named(3, 4);
// static Baz a = Baz(1, 2), b = Baz.named(3, 4);
static final c(5, 6), d(7, 8);
// static final c = Baz(5, 6), d = Baz(7, 8);
}
Nested enum declarations would conflict. Sadly a good point, so just the enum keyword won't work.
Mixins, abstract and sealed classes could work with const factory constructors (if we haven't allowed mixins to have factory constructors yet, we should).
Just foo(bar); is a valid untyped abstract function declaration, so some keyword or different syntax is needed. It would work for static const, or just final, but not for plain mutable instance variables. (Not a big loss, you could write var in front, but an inconsistency.)
Also doesn't work for local variables, and even with var in front of looks like an object pattern.
And on a parameter list, it's already a function typed parameter (not that you can declare values there, but the same syntax means something completely different.)
Should just make it look like markdown or yaml 😁
class const Foo(int x) {
- va(1)
- vb(2)
- vc(3)
;
}
Not very "Dart-ish", though. (And should * work too?)
Mixins, abstract and sealed classes could work with const factory constructors (if we haven't allowed mixins to have factory constructors yet, we should).
Fair enough regarding abstract and sealed classes, but mixins can not even declare a factory constructor.
Edit: I should note that factory constructors are not allowed in enums, so It's unclear if it's entirely necessary for such a feature to support factory constructors.
Just
foo(bar);is a valid untyped abstract function declaration, so some keyword or different syntax is needed.
I'm not sure you would need a different syntax altogether to disambiguate.
-
Most of the time the feature would likely be used in concrete types where you can't have abstract function declarations to begin with, so that leaves abstract classes, and sealed classes where the ambiguity can occur.
-
Enums are rarely defined with only one value, and the ambiguity only happens if you are defining only one value.
-
Most of the time you are not passing in a variable name you would be passing literal values like
foo(1), orfoo('hello')and notfoo(bar)wherebaris presumably a top-level variable. -
Currently in dart
enum A {a,;}is valid syntax. Note the trailing comma before the semi colon. So in the rare event that there is a conflict you could sayfoo(bar);is an abstract function andfoo(bar),;is an enum style constant.
const bar = 1;
abstract class Foo {
foo(bar),; // trailing comma required because
// ambiguous with abstract method
// alternatively, these should be unambiguous also
// foo(1);
// foo.new(bar);
const Foo._(this.value);
const factory Foo(int value) = _Foo;
final int value;
}
class _Foo extends Foo {
const _Foo(super.value) : super._();
}
const bar = 1;
class Foo {
foo(bar); // no trailing comma required because
// concrete classes cannot have abstract methods
const Foo(this.value);
final int value;
}