HaxeFoundation / haxe-evolution

Repository for maintaining proposal for changes to the Haxe programming language
111 stars 58 forks source link

Enum abstract instances #86

Open markknol opened 3 years ago

markknol commented 3 years ago

This proposal would allow instances as enum abstract values (generated as static singletons).
Currently this is not possible (error: Inline variable initialization must be a constant value)

Rendered version

RealyUniqueName commented 3 years ago

Won't this make our ordinary enums obsolete?

RealyUniqueName commented 3 years ago

I guess it's one more step to replace ordinary enums. The step is to make enum abstracts parameterized :)

enum abstract Person( { final name:String; final age:Int; } )  {
  final Mark = { name: "Mark", age: 21 };
  final John = { name: "John", age: 25 };
  final Elisa = { name: "Elisa", age: 28 };
  final Fifties(name:String) = { name:name, age:50 }
}
//...
switch person {
  case Fifties('Herman'): trace('Herman is 50 years old');
  case _:
}
grepsuzette commented 3 years ago

Some things are a bit confusing for me. Something from your example:

enum abstract Person({ final name: String; final age:Int }) {
  final John = { name: "John Bon", age: 65 };
  final Jane = { name: "Jane Dane", age: 18 };
  final Mark = { name: "Mark Hark", age: 36 };
  final Elisa = { name: "Elisa Disa", age: 42 };
}

That would mean a from { final name:String, final age:Int } clause is forbidden, right?

Another question (it was tipped in your final questions): Are non-final fields forbidden? For example:

enum abstract Person({ name: String, age:Int }) {
  final John = { name: "John Bon", age: 65 };
  final Jane = { name: "Jane Dane", age: 18 };
}

var p = John;
p.name = "Jane Dane";
p.age = 18;
switch p {
  case John:
  case Jane:
// Is it Jane or John? And if you set the age to 17?
}
Simn commented 2 years ago

We didn't reach a conclusion on this proposal in the haxe-evolution meeting today.

There are some open questions here related to the identity and equality of such values. We agreed to postpone the decision here and discuss this at a later point.

EliteMasterEric commented 6 months ago

Looking at this proposal, it seems that the core issue here is the inability to associate a single enumerated value with several data points. The syntax provided however seems complicated and confusing for this use case.

It may make more sense to extend the functionality of the bare enum type instead, to allow creating enum constructors which contain constant values.

// The syntax for this probably needs a second opinion or refinement
enum Color(Int, Int, Int) {
  Rgb(r:Int, g:Int, b:Int);
  Red(255, 0, 0);
  Green(0, 255, 0);
  Blue(0, 0, 255);
  Cyan(0, 255, 255);
  Magenta(255, 0, 255);
  Yellow(255, 255, 0);
  DarkRed(r:Int, 0, 0);
}

class Main {
  static function main() {
    var color = getColor();
    switch (color) {
      case Red(r, g, b):
        trace("Color was red, full intensity " + r);
      case DarkRed(r, g, b):
        trace("Color was red, intensity " + r);
      case Rgb(r, g, b):
        trace("Color had a red value of " + r);
    }
  }
}

Although I'm not sure whether this is better than just creating a static extension on the enum and storing the data in a switch/case structure on that.