Gleam - a view from non-functional perspective

Published: (December 14, 2025 at 12:42 PM EST)
3 min read
Source: Dev.to

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.

Back to Blog

Related posts

Read more »

I tried Gleam for Advent of Code

Article URL: https://blog.tymscar.com/posts/gleamaoc2025/ Comments URL: https://news.ycombinator.com/item?id=46255991 Points: 39 Comments: 12...

First-Class Functions in JavaScript

Introduction For developers learning JavaScript, the term first‑class functions appears frequently in discussions and documentation. In JavaScript, functions a...

java 8 (Stream API)

Features of Stream API - Declarative – Write concise and readable code using functional style. - Lazy Evaluation – Operations are executed only when a terminal...