# Why do most languages prefer complex enum instead of simple enum?

I don't know the standard words for these, but:

• complex enum is like enum { E1(t1: T1, t2: T2, ...), E2(...), ... }
• simple enum is like enum { E1(T1), E2(T2), ... }

The difference is for the constructor, the simple one always contain a tag and a type, the complex one contains a tag and multiple name-type pairs.

In a language with struct, you can always simulate complex enum by simple enum + struct, and the simple version feels much orthogonal.

But most languages even toy ones prefer complex enum. Why?

Example:

A complex enum:

enum Ast { TypeDef(name: Str, body: Ast), Ident(str: Str) }


simple enum:

enum Ast { TypeDef(TypeDef), Ident(Str) }
struct TypeDef { name: Str, body: Ast }

• @Isaiah I am confused. The question sounds crystal clear to me. What in particular do you think is confusing? The OP has given examples already. May 19, 2023 at 3:22
• Is this really true? What you call a "complex enum" is normally called an algebraic data type, though it is called an "enum" in e.g. Rust. On the other hand, enums in most languages I know are simply enumerated lists of values, often represented by consecutive integers, with no further structure. The kind you call a "simple enum" looks like what I would call a "sum type" or "tagged union", and I don't know of any languages that call this an enum. May 19, 2023 at 4:02
• @kaya3 I fear whatever terminology I use they might defined differently by other people. So I just came up with my own definition. For example what you calls sum type only have two constructors, but what I call "simple enum" can have multiple ones. May 19, 2023 at 4:07
• I don't think "sum type" has the connotation of only two constituents, but "tagged union" certainly doesn't. I think your phrase "simple enum" is misleading because people would expect this to mean traditional enums, i.e. enumerated lists of values with no further structure. In any case it is better to use established terminology rather than invent your own. May 19, 2023 at 4:13
• So, if "most languages" is correct, @molikto, please add at least one example. Jan 29 at 16:20

I feel mainly two reasons:

1. Structs corresponding to a single enum variant needs a name, while they have only one canonical use case, so it might be desirable to make these structs anonymous, hence the inlined version.
2. If your language supports tuples, it's definitely going to be a common pattern for users to have E1((T1, T2, ...)), which, the ability to unwrap the parentheses would be syntactically convenient. This is no longer a case when the syntax of enum variant types are not using parentheses already, see comments.
3. You can implement the simple enums in the core language and implement an elaboration feature. This is good for both compiler and the users.
4. Enums were evolved from C enums where no fields are allowed, which is a special case of n-ary (complex) enums, but slightly more cumbersome with simple ones.
• for 1, say I have enum Ast { TypeDef(name: ..., body:...) }. I always found I will need to define a function on TypeDef. So I ends up writting enum Ast { TypeDef(TypeDef) } where TypeDef isn't inlined. May 19, 2023 at 3:25
• for 2, is it a syntax thing? What if the syntax for tagging is t1@T1? Then the syntax will be less noisy May 19, 2023 at 3:26