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