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",
  }
}
  • Kacarott@aussie.zone
    link
    fedilink
    arrow-up
    2
    ·
    3 hours ago

    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.

  • fxomt@lemm.ee
    link
    fedilink
    arrow-up
    5
    ·
    8 hours ago

    Use a keyword, it’ll make your life a lot easier for parsing. If you’re reluctant on using “enum” as a keyword, you should check out OCaml/ML’s “type” keyword (they are the exact same contept: ADTs, but rust weirdly associates them with enums)

    Don’t use magic strings! Not only is this hard to check for errors while writing code, you also can’t tell easily if it is a normal string, or an enum.

    In my old project, my syntax looked like this:

    // Flavour and vec of ingredients
    type Food[T] {
      | Pizza str, vec[T]
      | Cake str, vec[T]
      | Soup vec[T]
    }
    

    not only is this easy to parse, i’d say it sticks true to its ML roots. You should check odin’s enum syntax if you’re keen on making a unique syntax.

  • calcopiritus@lemmy.world
    link
    fedilink
    arrow-up
    12
    ·
    12 hours ago

    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
    link
    fedilink
    arrow-up
    7
    ·
    12 hours ago

    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
    link
    fedilink
    arrow-up
    8
    ·
    15 hours ago

    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.eeOP
      link
      fedilink
      arrow-up
      2
      ·
      14 hours ago

      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.