Gleam: el lenguaje funcional tipado que corre en la máquina virtual de Erlang

Gleam lleva un tiempo llamando la atención de los programadores que buscan algo diferente dentro del ecosistema BEAM. No es Erlang, no es Elixir, pero corre sobre la misma máquina virtual y hereda todo lo que hace a esa plataforma tan especial: tolerancia a fallos, concurrencia masiva y distribución. Lo que Gleam añade es un sistema de tipos estático que ninguno de los dos anteriores tiene.

El lenguaje lo creó Louis Pilfold y llegó a su versión estable 1.0 en marzo de 2024. Desde entonces ha ido sacando releases con una cadencia muy regular, aproximadamente cada seis semanas. En enero de 2026 salió Gleam 1.7, con mejoras notables en el LSP y en el soporte para JavaScript. No es un proyecto experimental ni abandonado: tiene tracción real y una comunidad activa.

Por qué otra cosa sobre la BEAM

La máquina virtual de Erlang (BEAM) es una de las piezas de software más probadas en producción que existen. WhatsApp, Discord y varios sistemas de telecomunicaciones llevan décadas corriendo sobre ella. Erlang y Elixir son los lenguajes habituales para acceder a todo eso, pero los dos tienen el mismo talón de Aquiles: son dinámicamente tipados. Los errores de tipos aparecen en tiempo de ejecución, no antes.

Gleam resuelve exactamente eso. Con tipado estático e inferencia de tipos completa, el compilador detecta los problemas antes de que el código llegue a ejecutarse. No hay nulls (usa Option(a)), no hay excepciones (usa Result(ok, err)), y no hay herencia ni clases. El modelo es funcional puro, con variables inmutables por defecto.

Sintaxis: familiar si conoces Rust o ML

La sintaxis de Gleam tiene una influencia clara de Rust y de los lenguajes de la familia ML. Las funciones se definen con fn, las variables con let, y el control de flujo principal es case. Nada de if/else anidados para manejar variantes: aquí se usa pattern matching.

import gleam/io

pub fn main() {
  let message = greet("mundo")
  io.println(message)
}

fn greet(name: String) -> String {
  "Hola, " <> name <> "!"
}

El operador |> (pipe) es una de las características más usadas. Permite encadenar transformaciones de forma que se lee de izquierda a derecha, sin anidar llamadas:

import gleam/string
import gleam/io

pub fn main() {
  "hola mundo"
  |> string.uppercase
  |> io.println
}

Tipos propios y sum types

Gleam tiene un sistema de tipos algebraicos. Puedes definir records y tipos con variantes (sum types) de forma sencilla:

type Point {
  Point(x: Float, y: Float)
}

type Shape {
  Circle(radius: Float)
  Rectangle(width: Float, height: Float)
}

fn area(shape: Shape) -> Float {
  case shape {
    Circle(r) -> 3.14159 *. r *. r
    Rectangle(w, h) -> w *. h
  }
}

El compilador obliga a cubrir todos los casos en el case. Si añades una variante nueva al tipo Shape y no actualizas el case, el código no compila. Eso es justo lo que se busca con un sistema de tipos: que los cambios estructurales rompan en compilación, no en producción.

Módulos y la librería estándar

Cada fichero .gleam es un módulo. La librería estándar cubre lo más habitual: gleam/list con list.map, list.filter y list.fold; gleam/string con las operaciones de texto más comunes; gleam/result para trabajar con Result sin complicaciones.

import gleam/list

pub fn main() {
  let numbers = [1, 2, 3, 4, 5]
  let doubled = list.map(numbers, fn(n) { n * 2 })
  let evens = list.filter(doubled, fn(n) { n % 2 == 0 })
  // evens = [2, 4, 6, 8, 10]
}

Dos targets: Erlang y JavaScript

Gleam puede compilar a dos targets distintos. El target Erlang genera código BEAM que corre en la máquina virtual de Erlang, con acceso a toda la infraestructura de OTP, supervisores y procesos concurrentes. El target JavaScript genera módulos ESM que funcionan en Node.js, Deno o directamente en el navegador.

Esto lo diferencia de Elixir, que solo compila a BEAM. Con Gleam puedes usar el mismo lenguaje y el mismo sistema de tipos para código de servidor y para código de frontend. No es común, pero la posibilidad existe y hay proyectos que la aprovechan.

Herramientas del proyecto

El CLI de Gleam cubre todo el ciclo: gleam new nombre_proyecto para crear un proyecto, gleam build para compilar, gleam run para ejecutar, gleam test para lanzar los tests, gleam format para formatear el código y gleam docs build para generar la documentación. Sin dependencias externas, todo en un solo binario.

Los paquetes se gestionan a través de Hex, el mismo gestor que usan Elixir y Erlang, lo que da acceso a miles de librerías del ecosistema BEAM. El fichero gleam.toml define las dependencias y la configuración del proyecto, con la misma filosofía minimalista que el resto del lenguaje.

Para qué tiene sentido usarlo

Si ya tienes experiencia con Elixir o Erlang y echas en falta un compilador que te avise de los errores de tipos, Gleam es la respuesta más directa. También tiene sentido si vienes de lenguajes tipados como Rust y quieres explorar la concurrencia del modelo Actor sin salir de un lenguaje con el que te sientes cómodo.

No es un reemplazo de Elixir para todos los casos. Elixir tiene un ecosistema mucho más maduro, más librerías y más documentación. Pero Gleam tiene algo que Elixir no puede dar sin herramientas externas: la seguridad de tipos en tiempo de compilación. Para proyectos donde los errores de tipo son caros, esa diferencia importa.

En los próximos artículos de esta serie veremos el sistema de tipos y pattern matching en profundidad, la concurrencia con procesos y OTP, y cómo construir servidores HTTP con Wisp.

Imagen: Pexels / Myburgh Roux

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP