I'd like to clarify a little what the OTP is vs the BEAM - this article does an OK job at that explanation but confuses it a little.<p>The BEAM is the underlying VM used by Erlang, Elixir and Gleam. The BEAM provides the basic primitives like spawning processes, sending messages, handling messages etc. Processes are lightweight pre-emptively scheduled tasks, similar to go-routines or green-threads in other languages. These primitives are mostly lower level than you want to deal with on a day to day basis.<p>The OTP is a standard library built on top of that, to provide a convenient, battle-tested way of building systems. The GenServer is the most well known component - it simplifies writing code that handles messages one by one, updating held state, and sending replies. And bits around it to the caller, sending that message and getting to the reply is just like making a function call. GenServers are then managed by Supervisors that know what to restart when something crashes.<p>One notable difference between Elixir and Gleam is that Elixir gets to just re-use the OTP code as-is (with some Elixir wrappers on top for convenience). Gleam concluded that the OTP is built expecting dynamic types, and that for best results in Gleam they'd need to re-implement the key primitives. That's why the example shown is an "Actor" not a GenServer - it serves the same purpose, and might even fit in a Supervision tree, but isn't actually a GenServer.
Every time I see gleam examples I'm filled with calm, it seems like a very nice language to use.<p>I'm a data engineer so unless I feel like doing a lot of library development, I'll probably wait on the data ecosystem to advance a little bit more.<p>I hope it does some day, the BEAM feels like the perfect place for a distributed dataframe library to live.
Gleam is a very fun language to write in, and no need to start a project from scratch to explore it<p>I wrote Vleam to help incorporate Gleam into a Vue project, if you have one already<p><a href="https://github.com/vleam/vleam">https://github.com/vleam/vleam</a>
What I find very fun about Gleam is its minimalism. You've got functions, types, a case expression, and modules to organize them. That's it. No inheritance, no methods, no ifs, no loops, no early returns, no macros. And yet it's fairly productive and ergonomic to write.<p>For the most part, Gleam feels like it has gathered the best ideas from some interesting langs (perhaps a chimera of Rust, Go, ML and Lisp) and put them into one coherent, simple language. It's not that the ideas are new, they're just very well organized.<p>Gleam's labelled arguments are AFAIK a unique feature. (Edit: Nope see comments below) This lets you have named function argument appear differently to the caller than they do internally. The caller may way to refer by verb ("multiply_by") and the function may want to refer to it as a noun ("multiplier").<p>The `use <- ...` expression and pipeline operator `|>` can reduce boilerplate with nested function calls in a lot of cases. It's a nod to the ergonomic benefits of metaprograming without giving the user a full macro system.<p>Finally Gleam's tooling is the best in the business, hands down. The entire language, the compiler, package manager, LSP, etc, is all built into a single binary with an ergnomic CLI. Compared that to cobbling together a python environment or pretty much any other language where you need to assemble and install your own piecemeal toolkit to be productive.<p>Very excited to try Gleam more.
> Specifying what a function returns in Gleam is optional; due to type inference, Gleam will understand it anyway.<p>Oh yuck, I don't like that.<p>Function signatures are for HUMANS to read. Sure, the compiler can reach into a function implementation to glean what it returns, but that's no reason to force a human reader waste time on it as well.<p>"I'll accept this and this from you and then return that kind of thing to you."<p>vs<p>"I'll accept this and this from you and then return something to you that your supervisor will tell you if you're using correctly or not - or you could watch me as I work to see what it is I've made for you."
I've explored Gleam on a side project and I like it. The only real issue I had at the time was that it was a bit too niche to use for anything "serious", but that seems to be changing - which is cool.<p>I really want to see a demonstration that it can work with Phoenix LiveView though, or a Gleam equivalent with good IDE and tooling support. The productivity of the Phoenix LivewView + Elixir stack, and the ability to build async message-driven systems in concert with the UI remains a killer feature for me.
I just downloaded livebook yesterday, and it will be a great thing for gleam when you can include code blocks for gleam in livebook.<p>Also, if you're looking to pick up elixir or Erlang, I don't think there's a better tool. It's a jupyter-style notebook that feels really really good
It looks like a nice language with the {} syntax to tease all the C and Java developers out there. That's more important than it looks to help spreading the language.<p>The OTP example lets me state one of my few sore points about all the BEAM languages I worked with or looked at: the handle_this / handle_that madness. Search for "type AsyncTaskMessage" in the post to get there.<p>I don't want to write code like this (I omit the details, ... are ellipsis from mine)<p><pre><code> type AsyncTaskMessage {
Increment(reply_to: Subject(Int))
Decrement(reply_to: Subject(Int))
}
fn handle_async_task(message ...) {
case message {
Increment(client) -> {
code ...
}
Decrement(client) -> {
code ...
}
...
}
</code></pre>
I want to write code like this<p><pre><code> type AsyncTaskMessage {
Increment(reply_to: Subject(Int))
Decrement(reply_to: Subject(Int))
}
fn Increment(client) {
code ...
}
fn Decrement(client) {
code ...
}
</code></pre>
or any variation of that, maybe this OO-ish one (after all this is a stateful object)<p><pre><code> type AsyncTaskMessage {
fn Increment(reply_to: Subject(Int)) {
code ...
}
fn Decrement(reply_to: Subject(Int)) {
code ...
}
}
</code></pre>
Maybe one of the next BEAM languages will handle that automatically for us.
Has anyone very familiar to Elixir tried Gleam? I've been eyeing Elixir for years but I would miss types. Gleam looks nice but you lose Phoenix/Liveview which is 90% of the appeal of Elixir to me.
The main reason for using a BEAM language is to leverage multicore/concurrency conveniently and reliably. Gleam's OTP seems not as mature as that of Erlang or Elixir. If you want to write simple programs, then Gleam seems okay. If you want mature multicore or concurrent use, then I would think twice.<p>Here is a critical review of the officially listed limitations of Gleam's OTP:<p>1. <i>Lack of Support for Named Processes</i>: This is a significant limitation because named processes are essential for easy reference and communication between different parts of the system. Without support, developers might resort to workarounds that could lead to errors and inefficiencies.<p>2. <i>Untyped Global Mutable Variables</i>: The use of untyped global mutable variables introduces potential risks, such as runtime errors and unpredictable behavior, especially since they can be uninitialized. This undermines the type safety and reliability generally expected in functional programming environments.<p>3. <i>Limited Actor Abstractions</i>: The current scarcity of actor abstractions could restrict developers from implementing more complex or varied concurrency patterns, limiting the utility of the library until more abstractions are added.<p>4. <i>Unsupported OTP System Messages</i>: Dropping unsupported system messages can lead to unexpected behavior and bugs that are difficult to trace. Full support for OTP system messages is crucial for reliable and predictable actor-based concurrency.<p>5. <i>Uniform Shutdown Period for Supervisors' Children</i>: Not having different shutdown periods for child processes, especially for child supervisors, can lead to improper shutdowns and potential data loss or corruption. This deviates from the behavior in Erlang and Elixir, where more granular control is available.<p>6. <i>Limited Testing</i>: The lack of extensive testing, both in unit tests and real-world applications, indicates that the library might be unstable or have undiscovered bugs. This could affect its adoption and reliability in production environments.
The author mentions lustre, the web framework for Gleam that was inspired by Elm. I really like Elm. However, the limitation for me was the lack of a really robust component library. When I say component library, I don’t mean aesthetics but function. For example, a feature complete search bar with autocomplete, multiselect, create, delete, clear, etc. functionality. The reason I use typescript is because of component libraries like Mantine where generic components such as a search bar are already implemented, fully functional and accessible. I hope someone sees this gap and tries to fill it so that functional languages can be viable on the web!
I love the rust-like syntax. I write a <i>lot</i> of Rust and there have been times where I wished for a language on top of Rust with a tiny bit of OO patterns and a GC, so the borrow checker doesn't get in my way.
> All you need to get started with Gleam is already in this CLI. You dont’t have ANYTHING else check, there’s ZERO decision paralysis: THIS-IS-WHAT-WE-WANT. Javascript makes you pick a tool among hundred of options, for each tool provided in Gleam’s CLI.<p>This is undoubtedly true, although if Gleam ever becomes as popular as JavaScript, there will almost inevitably be the same set of choices to be made for Gleam.