1. 49
    Writing your own BEAM martin.janiczek.cz
    1. 3

      The syntax is crazy unreadable for me as a C, Rust, Go user. I honestly cant grasp the snippets fully

      1. 8

        Learning a bit of ocaml or Haskell will help with that

        1. 5

          Oversimplified, but possibly enough to make it more readable: It's a bit like the (rust) enum syntax, but used for more stuff. So the type Program bit might translate to (something like, since this won't work as-is):

          enum Program {
              End,
              Work { x: i64, y: Program },
              Spawn { x: Program, y: Pid },
              Send { x:Pid, y: String, z: Program },
              Receive {x: String, y: Program },
              Crash,
              Link {x: Pid, y: Program },
          }
          

          Then you've got the bits where variables of those enum types are assigned. So this:

          ex2 : Program
          ex2 =
              Work 5 <| \() ->
              End
          

          Is like:

          let ex2 = Program::Work { x: 5,
                      y: Program::End };
          

          Then the rest is case statements (like match statements), and code organized in a way similar to the variable declarations.

          1. 4

            Yeah, it's crazy how much syntax familiarity matters even when you know the concepts! Although I guess we have that with natural language, too.

            Here is the Elm code from Example 2, with a short description above each function and a Rust translation below it. https://ellie-app.com/x5qfKP2nr8Za1

            (And here is the Rust code on its own, since I wrote it anyway.) https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=edbe74894f2246941143912b2a75bab8

            NB: I messed the Rust equivalent a bit by making the continuations take 1 dummy arg instead of zero args.

            1. 7

              To write a function:

              // Rust
              fn plus(a: Int, b: Int) -> Int {
                  a + b
              }
              
              -- Elm
              plus : Int -> Int -> Int
              plus a b =
                  a + b
              

              To call a function:

              plus(1, 2)  // Rust
              plus 1 2    -- Elm
              

              To write an anonymous function:

              // Rust
              let callback0 = || { "Hi!" }
              let callback1 = |x| { fmt!("Hi, {}", x) }
              
              -- Elm
              callback0 = \() -> "hi!"
              callback1 = \(x) -> "hi!" ++ x
              

              Defining an enum type:

              // Rust
              enum UserAction {
                  Click(f64, f64),
                  Submit,
              }
              
              -- Elm
              UserAction
                 = Click Float Float
                 | Submit
              

              Constructing an enum variant:

              let x = UserAction::Click(1.1, 2.2);  // Rust
              x = Click 1.1 2.2                     -- Elm
              
              1. 3

                Thank you very much, it does make a lot more sense now

                1. 2

                  Yay! I'm glad I got to meet one of today's lucky 10 000 <3

              2. 3

                Syntax is superficial.

                1. 6

                  its subjective, but it still matters id say

                2. 2

                  I hope some LLM is able to port the examples into C-like pseudocode for you. Rust should be close enough to Elm thanks to supporting ADTs.

                  Happy to discuss specific ideas/paragraphs/snippets to help understanding too.

                3. 2

                  This is very cool. Not sure what I would use this for but cool it is.

                  1. 1

                    Impressive stuff! I look forward to reading it in detail, hopefully sometime soon.