Opinions on this syntax for enums?

I'm making a language with a lot of inspiration from rust and was experimenting with alternative enum syntax. It relies on literals to be types in order to convey information on the different options.

I don't really get on well with Typescript but having the ability to use literals as types is something I really liked as a lot of the times I use static string literals as errors. and having all the variants upcast through types makes it easier to do pattern matching.

Plain-text transcription of the image:

// using rust like enum syntax
Option<T> (
  | "Some" T
  | "None"
)

fn match_demo() {
  let some_option = Option "Some" "text";
  let none_option = Option "None";

  match some_option {
    "Some" "hello" => print("oh hi there"),
    "Some" text => print("Option is {text}"),
    "None" => print("Option is {text}"),
  }
}

// Or maybe more experimental syntax
Option<T> (
  | T
  | ()
)

fn match_demo2() {
  let opt = Option "something";
  match opt {
    "text" => "matching directly",
    var => "bind to variable",
    () => "nothing",
  }
}
26 points · 6 comments · view on lemmy.world

6 Comments

calcopiritus@lemmy.world · 15 pts · 1y

I hate both of them. The first one is very clunky with all the ". The second one is not self-docummenting at all, and it makes some enums impossible.

For example, you can't represent:

enum A {
    B(u32)
    C(u32)
    D
}

It would be

A {
    | u32
    | u32
    | ()
}

Also, the pipe is very awkward to type, specially depending on keyboard layout. Since it's a rare character. If you need to separate between enums and struts and really don't want to use the enum and struct keywords, you can use different delimiters, like:

A [
 u32,
 u32
]

B {
 u32,
 u32
}
FizzyOrange@programming.dev · 9 pts · 1y

Yeah I think you've made it worse than Rust in both cases. They clearly shouldn't be strings. And the second option is just unnecessarily confusing.

verstra@programming.dev · 8 pts · 1y (1 reply)

Wait, why literals? Could you not have just Some, without quotes? Or does this syntax imply that enums use these constants as variant tags?

Re: the pipe symbol - i wanted to also use this syntax but have decided against because pipes just looked stranger than commas.

Val@lemm.ee · 2 pts · 1y

The Idea is that the enum acts as a union, capable of holding any of the member types, It's not that different from using identifiers and when transpiling to rust I will probably only support variants beginning with string literals (or maybe generate them).

The main reason is that I could use type inference to define the variants in a returned anonymous enum.

I like the pipe symbol because it is useful for distinguishing between enums and structs without keywords. And I just personally think it looks better. And allow for pretty anonymous enums like (|String |Int) for something that can accept both a string and an integer.

fxomt@lemm.ee · 5 pts · 1y
[ removed ]
Kacarott@aussie.zone · 4 pts · 1y

The second syntax isn't actually enums at all, it's closer to a union type definition. You can't even define enum Colour = Red | Green | Blue using your second syntax.

badmin@lemm.ee · 1 pts · 1y

Fun Fact: Rust didn't always support leading pipes (which are optional), not even at v1.

Unless I'm hallucinating memories, the support was added with influence from Haskell.