I agree that all of these pattern matches should be expressible.

Under the current plan, we get there (at least) by:
 - RED is a constant pattern (well, Color.RED is a constant pattern, anyway.)  - Color(var red, _, _) is a deconstruction pattern, with an explicit deconstructor

The feature you are suggesting -- call it "record-style enum declarations", is a sound one; such an enum would acquire fields, constructors, deconstructors, and accessors, just like records.  It has come up a few times already; the reason we haven't done it so far is that the return-on-complexity is less than for records.  (It has its share of extra spec and compiler behavior, but the user benefit is less -- until we get to deconstruction patterns, it is just being able to omit the field and ctor declarations, which is something but not all that much.)  So we are holding this feature "on the shelf" until it seems more likely to pay its way.

(Further, we will want the exhaustiveness analyzer to be able to determine that the following switch is exhaustive:

    switch (paint) {
        case RED: ...
        case BLACK: ...
        case WHITE: ...
        case LinearGradient(...): ...
    }

by observing that RED/BLACK/WHITE covers Color, and Color+LinearGradient covers Paint.)

On 1/2/2020 3:52 PM, Remi Forax wrote:
Now that the design of Record is mostly stabilized, i think we should talk 
about the relation between an enum, a record and a sealed type.

As we have done with records, we can work backward from the pattern matching 
switch to see what we need for an enum.

So let suppose that like Java2D, we fill a shape with a Paint, Paint being an 
interface between a solid color and a gradient.
sealed Paint permits Color, LinearGradient { }
enum Color implements Paint{
   RED(255, 0, 0), BLACK(0, 0, 0), WHITE(255, 255, 255);
   private final int red, green, blue;
   ...
}
record LinearGradient(Point start, Color startColor, Point end, Color endColor) 
implements Paint {
   int getRed(int x, int y) { ... }
   int getGreen(int x, int y) { ... }
   int getBlue(int x, int y) { ... }
}

In that case, we may want to be able to switch on a special value (like RED), 
on an enum and on a Gradient which is a record.

int redAt(Paint paint, int x, int y) {
   return switch(paint) {
     case RED -> 255;
     case Color(var red, _, _) -> red;
     case LinearGradient gradient -> gradient.getRed(x, y);
   };
}

So should we allow record components on an enum with the following rule:
- either an enum use the record like syntax
   enum Color(int red, int green, int blue) { ... }
   and in that case, no supplementary fields are allowed.
- or an enum doesn't use the record like syntax and in that case, it's the 
classical enum.

The other solution, is to wait to have de-constructor, in that case we may not 
need a special syntax for enum.

Rémi

Reply via email to