Gleam is a type safe and scalable language for the Erlang virtual machine. Today Gleam v0.20.0 has been released, let’s take a look at what’s new.

Basic exhaustiveness checking

In Gleam the main way to define new data structures is with “custom types”.

pub type SchoolPerson {
  Teacher(name: String, subject: String)
  Student(name: String, year: Int)

Here we have defined a SchoolPerson type, which is either a Teacher record or a Student record.

When you get a SchoolPerson in your code you’ll need to check whether you’ve got a teacher or a student record so you can tell what you can do with the value.

pub fn which(person: SchoolPerson) -> String {
  case person {
    Teacher(..) -> "A teacher"
    Student(..) -> "A student"
Teacher(name: "Miss Percy", subject: "Physics") |> which
// -> "A teacher"

Student(name: "Koushiar", year: 10) |> which
// -> "A student"

Now imagine a new variant was to be added to the SchoolPerson type, a Technician record.

pub type SchoolPerson {
  Teacher(name: String, subject: String)
  Student(name: String, year: Int)
  Technician(name: String, domain: String)

If this was added but the which function was not updated with a clause to handle the new record then any code that called that function with a Technician would crash! The programmer has to find all the points at which a SchoolPerson is used and update the code appropriately.

This goes against Gleam’s philosophy of making the compiler do all the hard and error prone bits of programming. The programmer shouldn’t have to remember where to make changes for the program to be valid, the compiler should be responsible for finding all these locations and presenting them to the programmer to make a decide about what the logic should be.

With Gleam v0.20.0 the compiler will return a helpful error message when it finds that a custom type variant has not been accounted for when pattern matching.

error: Not exhaustive pattern match
  ┌─ ./src/thingy.gleam:2:3
2 │ ╭   case person {
3 │ │     Teacher(..) -> "A teacher"
4 │ │     Student(..) -> "A student"
5 │ │   }
  │ ╰───^

This case expression does not match all possibilities. Each constructor
must have a pattern that matches it or else it could crash.

These values are not matched:

  - Technician

Much better!

Currently the compiler supports a limited form of this exhaustiveness checking for custom types. Support for other kinds of values and for nested values will come in a future release, along with generated code optimisations that use the pattern matching information to improve runtime code performance.

Thank you to Michał Łępicki for this feature! As well as generally helping keeping the Gleam issue tracker squeaky clean and ship-shape.

Compilation from WebAssembly

The Gleam compiler itself can now be compiled to and used from WebAssembly. This enables Gleam code to be compiled in various new places, most notably within web browsers from JavaScript code.

With this new interface John Doneth has created a Gleam Playground, giving people a way to try out writing Gleam code without having to install anything on their computer or set up a development environment.

How does it work? I’m glad you asked!

The Gleam compiler is split into 2 components, core and cli, each of which is a project written in the Rust programming language. The core project is pure and has no functions which perform external IO (though it does mutate intemediate state internally), instead it accepts objects from outside which provide access to the filesystem, to the console to print diagnostic information, etc.

To create the Gleam compiler command line program the cli project wraps up core, injects the various IO performing objects it requires, and invokes the various core functions to provide the functionality requested by the user.

With this new version of the compiler a new alternative to cli has been created, called wasm. Using all the same APIs this project instead injects a virtual in-memory file system object and instead of providing a CLI interface it provides a JavaScript one, converting from Rust data to JavaScript data as required.

Using this JavaScript interface John’s playground project compiles Gleam code to JavaScript using Gleam’s JavaScript compiler backend, and then it evaluates this newly generated code, presenting the results to the user. This is done entirely within the browser, so it’s fast, reliable, and has no risk of being hijacked by malicious cryptocurrency miners.

Huge thanks to John Doneth for the WASM compiler interface and for his Gleam playground! In future I could imagine the playground being the foundation of a Gleam interactive tutorial that introduces newcomers to the language.

GitHub support

GitHub now recognises Gleam!

Gleam source code will now be syntax highlighted on GitHub and Gleam will show in the list of languages for a given repo.

Some Gleam source code on GitHub with syntax highlighting

This isn’t technically a Gleam feature, but it’s an exciting change that we’ve been looking forward to for several years so it’s worth including.

Thank you to everyone who has shared their Gleam code on GitHub. Without you this wouldn’t have been possible!

And the rest

Those are the big new things, but as always there’s lots of little improvements.

The diagnostic messages for type errors within Gleam’s try expressions have been greatly improved by Julien D. Thank you Julien! This should make one of Gleam’s less common features more approachable and easier to learn.

The build tool now copies the ebin directory into place if one is provided by an Erlang dependency that uses the rebar3 build tool. This is rare but is the case for latest versions of the popular cowboy package.

Project licence values are now verified as being valid SPDX licences, part of a wider BEAM ecosystem goal to validate licences used within the Hex package manager. Thank you to Jonathan Arnett for this contribution and for his thorough research into the state of play with BEAM package licencing.

The source code formatter’s output format has been improved with special cases to make some common patterns look better.

And as always, we’ve fixed some bugs 🐜

How can I try it?

Instructions on how to install the latest version of Gleam can be found on the getting started page of the website. Once installed check out the language tour for an introduction to the language.

For all the details of this release check out the changelog.

Supporting Gleam

If you would like to support me in making Gleam please consider sponsoring Gleam or asking your employer to sponsor Gleam. Every donation makes a difference, no matter how small, so thank you for your help.

⭐ Or alternatively give us a star on GitHub! ⭐

And thank you!

Gleam is made possible by the support of all the people who have sponsored and contributed to the project. Thank you all!

Thanks for reading! Happy hacking! 💜