Una de las ventajas prácticas de Gleam es que no empieza desde cero. Al compilar a BEAM, tiene acceso directo a décadas de librerías de Erlang y a todo el ecosistema de Elixir. No necesitas reimplementar lo que ya existe: puedes llamar a código Erlang o Elixir desde Gleam con una anotación de interop.
Esto es clave para un lenguaje joven como Gleam. Su ecosistema propio todavía está creciendo, pero la riqueza de librerías disponibles en Hex y en la BEAM es inmensa. Con interop, Gleam puede aprovechar todo eso desde el día uno.
@external: la puerta de entrada
La anotación @external le dice al compilador de Gleam que una función está implementada externamente, en Erlang o en un módulo JS. La sintaxis es:
@external(erlang, "nombre_modulo_erlang", "nombre_funcion") pub fn nombre_en_gleam(arg: TipoArg) -> TipoRetorno
El compilador acepta la declaración de tipos tal como la escribes, así que eres tú quien garantiza que los tipos declarados corresponden con lo que la función Erlang realmente devuelve. Si te equivocas en los tipos, el compilador no puede detectarlo, pero al menos el resto del código Gleam está verificado.
Llamar a módulos de Erlang
Erlang tiene módulos para casi todo: manejo de fechas, criptografía, operaciones con ficheros, sockets, ETS (tablas de memoria compartida entre procesos), y mucho más. Desde Gleam puedes usar cualquiera de ellos:
// Usar la función lists:reverse de Erlang @external(erlang, "lists", "reverse") pub fn reverse(list: List(a)) -> List(a) // Usar crypto:strong_rand_bytes de Erlang @external(erlang, "crypto", "strong_rand_bytes") pub fn random_bytes(count: Int) -> BitArray // Usar calendar:local_time de Erlang @external(erlang, "calendar", "local_time") pub fn local_time() -> #(#(Int, Int, Int), #(Int, Int, Int))
Muchas de las funciones de la librería estándar de Gleam son en realidad wrappers sobre módulos Erlang con tipos Gleam encima. Por ejemplo, gleam/list delega algunas operaciones al módulo lists de Erlang.
Llamar a librerías Elixir
Elixir compila a bytecode BEAM igual que Erlang y Gleam. Desde la perspectiva de la máquina virtual, una librería Elixir es solo otro conjunto de módulos BEAM. Puedes llamar a funciones de Elixir desde Gleam usando @external con el nombre de módulo que Elixir genera:
// Los módulos Elixir tienen el prefijo "Elixir." en BEAM @external(erlang, "Elixir.Jason", "encode!") pub fn json_encode(data: Dynamic) -> String @external(erlang, "Elixir.String", "split") pub fn string_split(str: String, pattern: String) -> List(String)
Para usar una librería Elixir en tu proyecto Gleam, la añades como dependencia en gleam.toml igual que cualquier paquete de Hex:
# gleam.toml [dependencies] jason = ">= 1.4.0" # librería JSON de Elixir
El tipo Dynamic: cuando los tipos externos son desconocidos
Cuando llamas a código Erlang o Elixir que puede devolver valores de tipo arbitrario (listas heterogéneas, atoms, maps sin schema definido), necesitas el tipo Dynamic de Gleam. Es el tipo de «cualquier valor BEAM», y para usarlo en código tipado tienes que decodificarlo explícitamente:
import gleam/dynamic
import gleam/result
pub fn parse_config(raw: Dynamic) -> Result(String, dynamic.DecodeError) {
dynamic.string(raw)
}
// O para estructuras más complejas
pub fn parse_user(raw: Dynamic) -> Result(User, List(dynamic.DecodeError)) {
dynamic.decode2(
User,
dynamic.field("name", dynamic.string),
dynamic.field("age", dynamic.int),
)(raw)
}
El decodificador verifica en tiempo de ejecución que el valor tiene la forma esperada y devuelve un Result. Así el código Gleam sigue siendo seguro aunque el valor venga de fuera del sistema de tipos.
Usar ETS desde Gleam
ETS (Erlang Term Storage) es el sistema de tablas en memoria de la BEAM: rápido, concurrente y compartido entre procesos. Desde Gleam se accede con interop Erlang:
@external(erlang, "ets", "new") fn ets_new(name: Atom, options: List(Dynamic)) -> Dynamic @external(erlang, "ets", "insert") fn ets_insert(table: Dynamic, tuple: #(Dynamic, Dynamic)) -> Bool @external(erlang, "ets", "lookup") fn ets_lookup(table: Dynamic, key: Dynamic) -> List(Dynamic)
La comunidad de Gleam está desarrollando wrappers tipados para las librerías Erlang más usadas, así que en muchos casos ya no hace falta escribir el interop manualmente.
La estrategia práctica
Para proyectos nuevos en Gleam, la estrategia habitual es usar primero las librerías nativas de Gleam (disponibles en Hex con soporte explícito para Gleam), y recurrir al interop cuando necesitas algo que no existe todavía en el ecosistema Gleam puro. El interop con Erlang es estable y bien documentado. El interop con Elixir funciona, pero requiere conocer el nombre de módulo que genera el compilador de Elixir.
Para los detalles de cómo construir un servidor HTTP completo aprovechando este ecosistema, el siguiente artículo de la serie cubre Wisp y Mist para servidores web en Gleam.
Imagen: Pexels / Pixabay
