Skip to content(if available)orjump to list(if available)

Gleam, Coming from Erlang

Gleam, Coming from Erlang

27 comments

·February 25, 2025

lanthissa

I really like gleam, the vibes are 'right' for me in that its got a strong type system and a functional style. Coming from scala land, that feels natural.

I think the author hit on a core challenge gleam will have to face, outside of dx. its main niche would be highly scalable type safe server apps, pretty similar to what scala is/was originally imagined as.

Its very hard to occupy that niche when by definition the projects you look to take on are large enough for languages to be heavily scrutinized. Your CTO wont really care if you choose rust, node, or go for some internal tooling. They will absolutely care about what is being used for core distributed services, and that just makes adoption hard.

epolanski

Most CTOs are great politicians, not great engineers.

h14h

I feel like Gleam's ability to compile to BEAM and JS is underutilized.

With how many people in the React/Typescript ecosystem are super excited about full stack type safety, this feature of Gleam feels like it's flying under the radar.

The pieces are there to have an unparraled DX for building everyday web apps, but the pieces haven't been assembled in a way that "clicks" for most people. At least, not that I've seen.

greener_grass

This already exists with F#, OCaml, Scala, Haskell... it doesn't seem to be a big draw.

h14h

Somehow didn't know this --I can't help but wonder why.

The effort to make JS work on the server has been much more successful than any attempt to make server languages work on the client. Nothing jumps out to me as an obvious technical reason this is the case -- maybe it's moreso an imbalance in effort & attention?

AzzieElbab

It is counterintuitive, but this feature did not do much for the Scala ecosystem. I wrote some toy projects but have not seen any in the real world.

lanthissa

some of the largest scala codebases under active development make heavy use of this feature.

evnp

Nice read, appreciate the balanced analysis. I love how `use` seems to have become the defacto keyword for "weird stuff happens here," we have Gleam's `use` now, `use` v `import` in Elixir... `useEffect` hijinx elsewhere...

asplake

Ooh, nice - Learn OTP with Gleam [1] – I was looking for something like that when I first looked at Gleam some time back

Edit: My (forgotten) comment when this was posted 10 months ago [2]: "So pleased to see this. Had fun playing with the language but at the time learning OTP seemed a big ask"

[1] https://github.com/bcpeinhardt/learn_otp_with_gleam

[2] https://news.ycombinator.com/item?id=40143559

cardanome

Honestly with Elixir starting to implement gradual typing and having an mature ecosystem and amazing backend framework, it is probably the better horse to bet on for bigger projects on the OTP.

Not to say say that Gleam doesn't had has it's place, it is a very interesting language, just that Elixir is already a good and battle-proven language.

lionkor

> Rust comes with all the systems programming overhead, which in my opinion is not a good bargain if you are not, you know, programming systems. Alas, I’m too old to pick up my own garbage.

Granted, I'm a systems programmer, but I find the difference between Rust's memory model and a managed memory model (like C#'s) not very big. The only difference is that it's trivial to leak resources in C#, and it's very hard to leak resources in Rust.

Happy to get recommendations of a language that has both a GC or similar managed memory model, and also can manage all other resources the same way.

What Rust does right is what C++ tried to do; RAII. Memory is a resource, file- and socket-streams are resources, mutexes are resources, and they are all handled via the same principle that we all know and intuitively understand: Scopes. By extension, reference counting enables doing an AND of all the scopes.

I have never found that to be more mental overhead than, say, python, C#, or Golang, where forgetting to close a file, or forgetting to call Dispose(), or doing it twice by accident, or using mutexes, is a common source of nasty bugs. Extend this to the concurrency model Rust has, where both threads and async can be used, and all the resource management and borrowing just cleanly extends to that to avoid concurrency bugs, and you have unparalleled resource management.

virexene

I'll have to disagree here.

Leaking resources in Rust is pretty trivial: create an Rc cycle with internal mutability. By contrast, in languages with a GC, cycles will be properly collected.

And there is nothing preventing GC languages from tying their non-memory resources to the lifetime of a value like Rust. See Python files, which are closed when the file handle is collected (ie. when all variables holding it go out of scope), and if that's not explicit enough, there's the "with" keyword to explicitly introduce a scope at the end of which the file is closed.

neonsunset

In Go, you have to explicitly do a defer. In C#, you just write `using var file = File.Open(...);`. Some methods handle disposal for you - you never interact with it if all you need is

  foreach (var line in File.ReadLines("example.txt")) { ... }
Here, file handle will be opened once you start enumeration and will be closed through enumerator disposal which is one of the calls foreach is desugared into (to be accurate, this specific implementation will also close the handle when reading the last line, but I'd expect user-authored type to do handle closure through dispose implementation only)

I agree that Rust implicitly inserting drop() by proving the exact place the value gets dropped at is superior, but C# experience is not exactly terrible either.

CharlieDigital

To be clear, `Dispose()` (aka `using`) is not the same as GC. It just cleans up unmanaged resources (connections, file handles, etc.) and marks the managed entity available for GC.

pjmlp

Depends, C# and .NET in general have support for manual memory management, it is a matter how it was allocated in first place.

People keep forgetting CLR was designed to accommodate C++ as well, and during the years some of those capabilities have been exposed to other languages in more easier ways than reaching out to C++/CLI.

pjmlp

Additionally, there are Roslyn analysers that will complain when we forget about using.

johnisgood

> don’t make it a reasonable choice for applications that require computation efficiency

Solely or alone (only) computation efficiency, otherwise use NIFs and/or Ports.

kristopolous

I've suspected gleam is really good candidate for generative coding for a while. Reading it and writing it seems to require a pretty small window of attention.

lanthissa

agreed, intuitively, referential transparency + strong types 'feels' like it should be the best ai programming language.

and exhaustive pattern matching + result types should help as well pushing issues out of runtime.

brap

It’s a nice language, and I like Lustre, but `use` is truly ugly.

I don’t understand why they didn’t make promises a first class citizen and added something like `await`. We’ve learned this lesson in JS already.

widdershins

Can you explain why you don't like `use` but you would like an `await` keyword?

As far as I can see, `use` is a superset of the `await` transformation that just happens to work in a lot more situations. It circumvents callback hell when you're working on the Javascript target [1] but also de-indents lots of other code like handling results [2].

[1] https://github.com/gleam-lang/javascript [2] https://erikarow.land/notes/using-use-gleam

mightyham

Your complaint doesn't make sense to me because `use` is essentially the same thing as `await` in JS. It hoists the rest of the function body into a callback so that the logic can be flat. In fact, `use` is an improvement on `await` because it is more generic and avoids the issue of function coloring. Promises also don't make as much sense in BEAM languages where callback based asynchronous code is not all that common or encouraged.

greener_grass

The JS approach is worse than a do-notation approach because it is not extensible. Now we are stuck without cancellation token propagation (forever?)

null

[deleted]

innocentoldguy

I'm sure Gleam fits a niche—maybe something similar to Elm?—but I can't justify using it over Elixir because I'm not willing to trade things like

1. Full access to the BEAM.

2. Full access to OTP behaviours and other features.

3. Lisp-style macros.

4. Late-bound function calls.

5. Dynamic message passing.

6. Native supervision trees.

7. Internationalization.

for static types. Doing so feels like trading my car's engine for a suction cup phone holder.

(EDIT: Fixed formatting.)

null

[deleted]