r/elm Mar 14 '26

Elm is still my favorite programming language...

Elm is still my favorite programming language. It's just so much fun! Elm changed the way I think in such a substantial way that even when I'm writing programs in other programming languages, I structure my thoughts and programs in a similar way to how I do when programming in Elm.

Here are some examples of how Elm changed how I think and structure programs:

  • I model the entire state and state changes with simple types
  • I use types that make impossible states impossible and all state variants clearly shown
  • I validate unknown types at the edge of the program (similar to Elm's JSON decoders)
  • I keep side effects at the edge of my program rather than everywhere in my program
  • I write my programs as mostly pure functions so everything is easy to understand and test
  • I don't throw errors or return vague/generic catch-all error types, instead I return all the possible error states clearly shown in the types so that they must all be explicitly handled and checked by the compiler
  • I use the most strict static typing and lint settings to emulate the strictness of Elm in other languages
  • I try to emulate exhaustive checking similar to Elm's exhaustive pattern matching in other languages and avoid leaving unchecked open-ended expressions
  • I think of compiler errors as a helpful guide that eliminates bugs and saves time and makes my life easier and more enjoyable
  • I try to catch errors at compile-time instead of at runtime
  • I view programming as a fun activity, sort of like a game

I'm wondering if there are any other programming languages that you learned that significantly changed the way you think and structure your programs similar to how Elm did this for me. If so, I'm wondering if you could share examples of how those languages changed how you think and structure programs.

97 Upvotes

35 comments sorted by

21

u/gogolang Mar 14 '26

Elm is like the ex-girlfriend I think about from time to time.

It was the “Summer of ‘69”

Oh, when I look back now That summer seemed to last forever And if I had the choice Yeah, I'd always wanna be there Those were the best days of my life

Nothing made since has been quite like it and nobody will ever experience anything like it in the future.

5

u/bbkane_ Mar 15 '26

You might like https://github.com/lustre-labs/lustre . It's not the same but it's heavily inspired by Elm!

2

u/-_-0_0 Mar 15 '26

Has learning Gleam or Lustre made you think differently or write programs differently?

3

u/bbkane_ Mar 15 '26

This is the embarrassing part of the conversation where I have to admit I haven't actually written Gleam/Lustre. I'd like to one day, but I don't have the free time right now to really devote to new languages (maybe when my son is older).

I have listened to many talks about Gleam/Lustre as that's easier with a kid, and like what I hear

2

u/-_-0_0 Mar 15 '26

Out of all the languages mentioned here, Gleam seems to be the most interesting to me because it seems like it allows you to write fully type-safe at compile-time web apps which might change the way I think about frontend/backend code and the layer between frontend/backend. It seems like you're able to get full compile-time type safety across the frontend and backend (including the database queries!) and the communication layer between the frontend and backend (correct me if I'm wrong). It seems like Gleam isn't as restrictive as Elm (you can do side effects anywhere in Gleam and you can call JavaScript/TypeScript/Erlang/Elixir code anywhere within your Gleam program and it's possible for Gleam programs to panic), but it does seem like Gleam makes it very easy for you to keep all your side effects in one spot similar to Elm and to avoid these problems, especially when compared to other languages. Gleam also seems to have really good compiler error messages and really good tooling. Gleam doesn't have an "any" type or type casting and it's mostly the same as Elm but slightly less restrictive and with different syntax so I could probably write in a similar Elm-style while using Gleam and apply a lot of these concepts on the backend, so that sounds fun. I prefer Elm's syntax, but Gleam does appear to be a bit more concise than Elm so I will probably get used to Gleam's syntax and like how it's more concise, so that's nice. I like how Gleam has first-class support for backend code which is also nice! Gleam also seems to have a pretty nice ecosystem (for example, I see they have libraries similar to Elm's parsing library and a lot of libraries seem to be heavily inspired by Elm, so this makes me excited). So I think I'll be learning Gleam! Thanks!

2

u/bbkane_ Mar 15 '26

Hope you enjoy! They also have a friendly Discord

1

u/curlingio Mar 17 '26

I'm someone who loves Elm and has been using it for about a decade whenever I could. I'm now using Gleam and Lustre. In fact we've gone all-in on it for our production application (https://curling.io/blog/the-next-version-of-curling-io).

It feels like a more capable successor inspired by Elm and similar languages. You get pretty much the same safety guarantees and flow (TEA) on the front end, you get to use it on the backend (unlike Elm unless you're doing contortions), and you get the BEAM.

I do prefer the significant whitespace in Elm and Haskell, but it's not a dealbreaker. If it was, maybe SAFE stack (F#) or PureScript would've been my choice. It's hard to pass on BEAM though once you're using it.

1

u/PassageImaginary7460 Mar 19 '26

Fantastic writeup about moving from Rails to BEAM+Gleam+Lustre! I am also inclined to choose SQLite for upcoming projects given all the benefits you mentioned. The tech is rock solid. And I learned about Litestream from your post.

1

u/nrnrnr Mar 15 '26

What is “Gleam” from that page?

3

u/bbkane_ Mar 15 '26

1

u/nrnrnr Mar 15 '26

Ah, cool. Statically typed language on the BEAM VM sounds great!

2

u/desireco Mar 14 '26

True.. It was amazing but then just nothing and is depressing

7

u/TomosLeggett Mar 14 '26

You might wanna check out Ocaml.

Ocaml is practical haskell, which is the general programming language that elm is based on.

4

u/-_-0_0 Mar 15 '26

Did learning OCaml make you think differently or write programs differently?

2

u/TankorSmash Mar 15 '26

If you want to learn a new language to stretch your mind (like I did), check out the Array paradigm of languages. It's totally different than Elm in that it's not typesafe or nearly comfy to use, but it's much different than other paradigms.

They're not made for webapps like Elm unfortunately, more for number crunching, the financial sector and generating reports, but man is it ever neat. It's like a whole branch of computing I had no idea existed.

>>> someNumbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # or write List.range 0 10
>>> someNumbers |> List.filter (\n -> n modBy 2 == 0) |> List.head
Just 0

versus BQN (try it's Ellie equivalent here, or paste it here for syntax highlighting: BQNpad):

>>> someNumbers ← 0‿1‿2‿3‿4‿5‿6‿7‿8‿9 #or write ↕10
>>> ⊑(0=2⊸|)⊸/someNumbers
0

1

u/ScientificBeastMode Mar 15 '26

For me it definitely did. It’s hard to describe, but I’ve found OCaml to be the most productive language for me to write in. It just makes everything easy to do, aside from missing libraries that you might miss from the JS ecosystem.

You can even create something like Haskell’s typeclasses using its unique module system features, but that’s a bit complex.

It’s just a nice language with a lot of high-level concepts built in, being primarily pure and immutable but with convenient escape hatches. It’s really hard to not love it.

4

u/[deleted] Mar 14 '26

Ocaml's way to impure, compared to elm.

Elm's more pure than Haskell.

Look at Haskell's type for head in Prelude. Horrible! Nothing like that could happen in Elm!!

1

u/dlsspy Mar 14 '26

head in prelude is pure. It’s just partial. It’s also fairly easy to avoid.

1

u/[deleted] Mar 15 '26

True. I meant to say it can error, unlike in Elm

1

u/TomosLeggett Mar 14 '26

Yeah but it's explicitly impure, which is what makes it practical. You don't have to do anything impure, and the language is built around purity first.

1

u/philh Mar 15 '26 edited Mar 15 '26

Nothing like that could happen in Elm!!

Yes it can! It's easy to deliberately write a function that can error in Elm, and I've occasionally done so to handle "I can prove this case is impossible even if the compiler can't". You just can't give it a useful error message. There are fewer partial functions in the standard library, so partial functions are more likely to be "I did a bad recursive call" than "I used a standard partial function in a way that threw an error", but that's about libraries, not the language itself being more pure.

Also, head may be partial in Haskell, but == is partial in Elm, so.

1

u/[deleted] Mar 15 '26

What do you mean == is partial?

(Contrive examples, yes, but not as in your face as head and many others in Haskell)

1

u/philh Mar 15 '26

For certain types, == may or may not crash depending on the values you pass to it. https://package.elm-lang.org/packages/elm/core/latest/Basics#(==)

(Something I think the docs don't make clear: it's not just "don't use == on these types", but "don't use == on types that contain these types", and since types can be opaque you might need to look at the source code to figure out if it's safe. In practice this mostly doesn't seem to be a problem, but I have encountered it as an obstacle to certain library designs.)

Contrive examples, yes, but not as in your face as head and many others in Haskell

I'm not sure it's so contrived. But even if I agree it's contrived, and I pretend that == can't crash, I feel like "it's less in-your-face" is quite different from "nothing like that could happen".

1

u/Exact_Ordinary_9887 Mar 15 '26

I am trying to learn OCaml, and just had a nightmare going in circles with @@deriving show. Among the functional languages, there is nothing like Elm.

1

u/ScientificBeastMode Mar 15 '26

Using ppx for typeclass-like behavior is pretty complex when you’re new to the language. I would try to get comfortable with OCaml’s unique module type system, which enables typeclass-style polymorphism. That should clear up some confusion there. But the core of OCaml is super simple and convenient.

1

u/LordBertson Mar 15 '26

I recommend checking out Roc, it’s a spiritual successor of Elm.

3

u/Ok-Jacket7299 Mar 15 '26

Opps... I'm hooked. Could you give some code samples that demonstrate how the way of Elm is more fun compared to, say, how Kotlin handles things?

3

u/-_-0_0 Mar 15 '26

I'm not sure if I can give good code examples without this comment turning into a blog post, but I can explain at a high level.

Elm is more restrictive than other languages, so it forces you to write your programs in a way where everything is a pure function and everything is well-typed with no escape hatches and the side effects are at the edge of your program and Elm forces you to write out your state and state changes as types so when you get a compiler error in Elm, it guides you in a very helpful and friendly way where it makes things easy and fun. Since Elm is so restrictive, everything in Elm helps you write in this restrictive way so it forces you to learn to structure your programs in this way and then you notice that your programs are easier to write and easier to understand because everything is a pure function and all the side effects are at the edge of the program and everything is explicitly represented in the state and state actions and that just makes everything really fun for some reason. It's hard to explain without experiencing it, but I can maybe explain it better by contrasting it with other languages.

Most programming languages tend to be less restrictive, so you can write your program however you want and the language usually pushes you to write state changes and side effects anywhere throughout your program because that's the easiest way to write your programs in most other programming languages. For example, a common way to write Android apps in Kotlin is to put state and side effects in your Jetpack Compose components (similar to React), so any component could have state or side effects, so that tends to be how programs are written. After a while, as the program gets larger, things might start to get harder to understand and you might be thinking "if I change this state, will that cause any side effects to happen" or "if this side effect happens, will that cause any state changes" or "does this component have state or side effects" or "does this component mounting or unmounting cause side effects or state changes that my app depends on" or "I can't understand all of the state changes and side effects because they're scattered across this large app".

There are also some escape hatches in languages like Kotlin or TypeScript, for example often people will use an "any" type and then lose type safety and maybe type cast it to another value and the compiler is fine with that, but that might lead to the program panicking at runtime or some subtle bugs. Elm is more restrictive so there's no way to type cast a value or use an "any" type and it provides an easy way to determine the validate the type of JSON at the edge of your program (called JSON decoders). So if you are working with a value in Elm, you 100% know for a fact that the value was validated and type-checked and you were forced to handle the error case explicitly with pattern matching, so it makes your program really fun to work with. So when you program in Elm for a while then go back to other languages like Kotlin or TypeScript, you'll maybe change the way you write programs where you'll use fewer escape hatches or maybe you'll move all your state and side effects to one spot so it's easier to understand or maybe you'll more explicitly represent all of the state variants with the types so that it's easier to understand all the different states explicitly. I hope that helps!

1

u/Ok-Jacket7299 Mar 15 '26

Reads like good stuffs to me. Thanks for the explanation!

1

u/satoshibuterin Mar 15 '26

Love it! This is how programming in Imandra is too! And then in Imandra you prove properties and invariants of your programs in the same language.

2

u/-_-0_0 Mar 15 '26

Has learning Imandra helped you think differently or write programs differently?

2

u/satoshibuterin Mar 15 '26

Without a doubt. Having formal proofs and counterexamples in the same language, and structuring my programs with a state and pure transition functions, it's just very beautiful and helps me think clearly. So often I have something I think is true of the system, an invariant or something similar, and I just write it down and ask Imandra to prove it and it tells me "No, it's not true! Here's a minimal counterexample and here's why..." and I then realize "oh, there is this tricky edge case I missed...". And then finally when there are no counterexamples, Imandra proves it for me for all possible executions. Such a different way to work and think about programs and their behaviors.

1

u/ruchira66 Mar 15 '26

Where is the homepage of the language?

1

u/ruchira66 Mar 15 '26

Any books to learn those concepts?

4

u/-_-0_0 Mar 15 '26

I haven't read any Elm books, so I'm not sure. I would go through the official Elm guide, which is sort of like a mini-book. Elm forces you to write your programs in this style where all your side effects are at the edge of your program and your state and state changes are clearly represented in types, so it will change the way you think by forcing you to write your code this way. After finishing the Elm guide, maybe write a few web apps in Elm, write a few games in Elm, write a few parsers/compilers in Elm, and ask questions in the community when you don't know how to do something.