Pattern matching + Enum proposals

Hi Nick, I’m sorry for the delay responding, thank you for the ping.

Why is this a goal? Your proposal is hard for me to understand, because it starts with an elaborate design, but doesn’t have a motivation section. The motivation is spread through the rest of the document.

There are significant problems that I see with it though, for example:

var highlight = Color.Red
...
if ...:
    highlight = Color.Blue

Would fail to compile, because ‘highlight’ would not infer to being type “Color”, it would infer to being the type of the case. This would be very surprising to users, and attempting to correct this would add special cases and break composability.

I don’t understand the use-case for this - I personally haven’t experienced this need in the sorts of things I’ve programming in other languages. That said, I also don’t understand how this works. Pointer isn’t automatically covariant on its element type, we’d have to add implicit conversions etc to enable this. That would add a lot of complexity.

The design doc mentions anonymous cases and anonymous unions because they came up in previous discussions, but it also lists a number of significant problem they introduce. While they’re appealing, it is far from obvious to me that they justify the complexity needed to solve this. In this case, I can definitely see use-cases for them, e.g. it would be convenient to provide “typed bools” e.g. :

def set_light(state: .on | .off): ...

That said, while this is “handy”, this is “just sugar” for something like:

enum LightState:
    case on, off
def set_light(state: LightState)

I am far from convinced it is worth adding complexity to support this.

Separate from that, the biggest concern I have is the fundamental design. By turning cases into types, you’re making another way to define a new type. Why do we want “another way to define a type” vs using the existing way we have to do this?

I don’t see why:

enum Color:
    case Red
    case Green
    case Blue

    @fieldwise_init
    case struct RGB:
        var r: Int32
        var g: Int32
        var b: Int32

    @fieldwise_init
    case struct HSL:
        var h: Int32
        var s: Int32
        var l: Int32

Is better than:

@fieldwise_init
struct RGB:
    var r: Int32
    var g: Int32
    var b: Int32

@fieldwise_init
struct HSL:
    var h: Int32
    var s: Int32
    var l: Int32

enum Color:
    case red
    case green
    case blue
    case rgb(RGB)
    case hsl(HSL)

The later has much better separation of concerns, composability, and stacks more cleanly on top of all of the other things that you can do with structs. I wouldn’t want to see trait conformances, requirement clauses and all the other decorators on enum cases: I’d much rather have “simple things that compose”.

Thank you for taking the time to write this up - it is an interesting design point and one that could certainly work, but I don’t think it is aligned with what we want Mojo to be.

-Chris