# Pattern matching + Enum proposals

**URL:** <https://forum.modular.com/t/pattern-matching-enum-proposals/3473>\
**Category:** Language Design\
**Tags:** discussion\
**Created:** [September 7, 2026, 2:54am UTC](https://forum.modular.com/t/pattern-matching-enum-proposals/3473 "2026-09-07T02:54:29Z")\
**Posts on this page:** 1\
**Showing post:** 50

<div class="post-metadata">

**Author:** ![clattner](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/clattner/32/201_2.png) [@clattner](https://forum.modular.com/u/clattner)\
**Post date:** [October 15, 2026, 9:19pm UTC](https://forum.modular.com/t/pattern-matching-enum-proposals/3473/50 "2026-10-15T21:19:05Z")

</div>

> [@Nick](#):
>
> Alright, I’ve now had enough time to study @clattner’s proposal and formulate a proper response. Here’s my feedback.

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

> [@Nick](#):
>
> My main concern about Chris’s proposal (as currently written) is that it leads us away from being able to treat cases as structs.

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:

```auto
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.

> [@Nick](#):
>
> ### Guaranteed compatibility between `Pointer[MyEnum]` and `Pointer[MyEnum.Case]`
> 
> Earlier I mentioned that a case struct is not “just” a payload type, because it also (implicitly) stores a discriminant, and has the size and alignment of the parent enum. Here is where that distinction comes into play.
> 
> ..
> 
> Consider the earlier example where we partitioned colors into RGB and HSL. Let’s imagine we want the partitions to store pointers rather than copies of the colors:
> 
> ```mojo
> var colors: List[Color] = get_colors()
> var rgb_colors: List[Pointer[Color.RGB, _]] = []
> var hsl_colors: List[Pointer[Color.HSL, _]] = []
> 
> ```
> 
> Now let’s imagine we’ve defined a function that takes an immutable pointer (or reference) to a color:
> 
> ```mojo
> def foo(color: Pointer[Color, _]): ...
> 
> ```
> 
> It would be great if we could safely pass a pointer to an RGB or a HSL color to this function, even though they expect a more general Color pointer.

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.

> [@Nick](#):
>
> Here’s how we might declare a color variable whose case is restricted to be an RGB or HSL color:
> 
> ```mojo
> var c: Color.RGB | Color.HSL
> 
> ```
> 
> Just as in Python, this “union operator” would not introduce a new class or struct. The type of `c` would be a subtype of `Color`, and its runtime representation would be identical to a `Color`. As in Python, we can then rely on the presence of the discriminant to test which (sub)type the variable holds at runtime:

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. :

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

```

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

```auto
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:

```auto
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:

```auto
@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

---

_[View the full topic](https://forum.modular.com/t/pattern-matching-enum-proposals/3473)._
