Partial and unfair tour of Gleam
With every rainbow, a bit of rain

I keep hearing people praising systems built on top of the BEAM virtual machine. Unfortunately programming with dynamically typed languages like Erlang or Elixir is really not my thing for production code. But it doesn't have to be so! Gleam is a statically-typed functional programming language that targets both BEAM and JavaScript (it also has its own runtime).
After listening to the excellent interview of Giacomo Cavalieri on the FuncProg podcast (hi Christoffer!) I thought I would do the online tour of Gleam to get a better taste of it.
Here are my first impressions in three convenient buckets: "noice", "hmmm...", "hell no!".
Noice
FP language with familiar constructs for lists, options, results, partial application, etc...
Pattern matching with reasonable machinery: named values, catch-all, guards, elided values, alternatives, etc...
Records with record getters / updates, enums, variants.
Type aliases, opaque types.
Simple language, easy to learn, nice error messages.
Interop story with JavaScript and Erlang (with the
@externalannotation)The
gleambuild tool seems to be inspired by cargo:Using a TOML file
build,test,fmtout of the box.With nice dependencies management (from Hex, local paths, or a git repository)
Did I mention statically-typed?
Hmmm...
The
<<>>syntax for bit arrays with tags likeutf-8. Just hmmm, because I'm not familiar but could be noice.No exceptions but 3 keywords that can panic:
todo,panic,assert.//(expression),///(function) and////(module) as a way to start comments.No macros but 3 predefined annotations:
@deprecated,@external,@target.Function syntax with
fn(a) -> b. Why not the simplera -> b? Hard to beat Haskell there.Generics syntax with parentheses
List(Int). Why does everyone insist on doing that differently 😫?Haskell:
List aScala:
List[A]Rust:
List<A>OCaml:
'a list
The
gleambuild tool creates a new project with a Github workflow +.gitignoreout of the box. Can this be customized?
Hell no!
Division by 0 is equal to 0.
No syntax for early return of results, like
?in Rust.|>can apply a value as the first parameter of a function (likef(a: Int, b: Int)) or as the argument to a 1-argument function (likefn(Int) -> Int). That looks troublesome.A
brand new concept[1] for named parameters:fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool.inandsatisfyingare "labels" and can be used to passed named values:all(in: [1, 2], satisfying: fn(x) { x > 3 }).Short-hand syntax for named parameters do we really special support for this?
Expressions have to be grouped with
{}, like{ 1 + 2 } * 3and not with regular parentheses. I thought it was to parse more easily tuples, but they have their own ugly syntax#(1, 2, 3). What's wrong with(1, 2, 3)? Good thing that lists are just[1, 2, 3].Nilvalue representing a "unit/void" type. That hurts me as a Scala programmer.asas a keyword just to pass a message totodo/panic/assert.A keyword,
echojust to output debug statements.
Conclusion
I am definitely happy that a statically-typed programming language exists in the BEAM ecosystem and would love to use Gleam if I had to use BEAM. My main concerns are:
The syntax is designed to be lightweight but feels a bit ad-hoc. I feel we could have done better here.
The type system looks minimal (no type classes for examples) but this might be the price to pay for an easy interop story with BEAM and Javascript.
The OTP story is supposed to be a strong selling point (systems with great uptime!) but the OTP library seems to be still in infancy and easy concurrency could sold better on the front page IMO.
gleamseems to follow the path ofcargobut with less power (workspaces, plugins, etc...)
I apologize in advance to Gleam authors and fans for writing possibly inaccurate or unfair comments on this post. I hope I can come back and write some more serious code with Gleam to get a more informed opinion in the future!
[1]: Brand new to me! Swift also has parameter labels.



