Gleam - a view from non-functional perspective
Source: Dev.to
Abstract
For those who don’t know, Gleam is a high-level, statically‑typed functional language that runs on BEAM – Erlang’s VM. It was voted the 2nd most admired language (right after Rust) in the Stack Overflow Developer Survey 2025. In March 2024, version 1.0.0 was released, indicating that the authors consider the language fairly mature. But is it practical to write larger projects with Gleam?
Motivation
I decided to write a classic Game of Life in Gleam. This project usually takes only a few hours even in an unfamiliar language, yet it is complex enough to require loops and matrices. This post lists my thoughts after completing the project.
Implementation
A few words about the development experience with Gleam:
- VSCode plugin:
- Language Server Protocol support:
- Good tutorials are available:
Stdlib – batteries not included
First, the Gleam stdlib does not provide 2‑D arrays (matrices). Fortunately, you can implement them yourself:
pub type Arr2d(a) = glearray.Array(glearray.Array(a))
Using glearray instead of gleam/list allows for more efficient indexed access. You also need functions for getting and setting elements:
pub fn get_el(arr: Arr2d(Bool), x: Int, y: Int) -> Result(Bool, Nil) {
case glearray.get(arr, at: y) {
Ok(row) -> glearray.get(row, at: x)
Error(_) -> Error(Nil)
}
}
pub fn set_el(arr: Arr2d(Bool), x: Int, y: Int, v: Bool) -> Arr2d(Bool) {
case glearray.get(arr, at: y) {
Ok(row) ->
case glearray.copy_set(row, at: x, value: v) {
Ok(new_row) ->
glearray.copy_set(arr, at: y, value: new_row)
|> result.unwrap(arr)
Error(_) -> arr
}
Error(_) -> arr
}
}
The code isn’t complicated, but you have to write it yourself if you need matrices. Most mainstream languages—including functional ones like F#—provide built‑in matrix support.
Loops
Gleam, being a functional language, famously doesn’t have loops. You can rewrite code using recursion, but that often makes it harder to reason about. A common pattern to emulate a for loop is:
list.range(0, count - 1)
|> list.each(fn(e) {
echo e
})
Compare that with the more concise F# loop:
for e in 0 .. count do
printfn "%d" e
If you need to perform computations inside the loop, you’ll typically use list.fold instead.
Auto‑formatting
Like Go, Gleam auto‑formats your code, and the formatting is not customizable by design. While the rationale is understandable, a one‑size‑fits‑all approach can be limiting; offering a set of default options that can be tweaked would be preferable.
Conclusion
Although this article highlights some drawbacks of Gleam, I actually like the language. It works well for tasks that involve iterating over collections or writing simple parsers. Gleam can also serve as an introductory functional language, being less intimidating than Haskell, Scala, and others.