Published 23 Feb, 2022 by Louis Pilfold
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.
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.
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!
- Adam Bowen
- Adam Brodzinski
- Adi Iyengar
- Alexander Koutmos
- Ali Farhadi
- Anthony Scotti
- Arnaud Berthomier
- Arno Dirlam
- Arto Bendiken
- Ben Marx
- Ben Myles
- Brian Glusman
- Bruno Michel
- Carlos Saltos
- Charles Chamberlain
- Chew Choon Keat
- Chris Lloyd
- Chris Young
- Christian Meunier
- Christopher Keele
- clangley
- Clay
- Cole Lawrence
- Colin
- Cristine Guadelupe
- Damir Vandic
- Dan Dresselhaus
- Dan Mueller
- Dave Lucia
- David Armstrong Lewis
- David Bernheisel
- David Flanagan
- Dennis Dang
- Ed Kelly
- Edon Gashi
- Eric Meadows-Jönsson
- Erik Terpstra
- Filip Figiel
- Florian Kraft
- fly.io
- Gitpod
- Graeme Coupar
- Guilherme de Maio
- Gustavo Villa
- Harry Bairstow
- Henry Warren
- Herdy Handoko
- human154
- Ian González
- Ingmar Gagen
- inoas
- Ivar Vong
- James MacAulay
- Jechol Lee
- Jeff Kreeftmeijer
- jiangplus
- Joe Corkerton
- John Palgut
- JohnDoneth
- Jonathan Arnett
- josh rotenberg
- José Valim
- Josías Alvarado
- João Veiga
- Kapp Technology
- Kieran Gill
- Lars Lillo Ulvestad
- Lars Wikman
- Marcel Lanz
- Marcin Puc
- Marius Kalvø
- Markus
- Martin Janiczek
- massivefermion
- Matt Van Horn
- Memo
- Michael Anhari
- Michael Chris Lopez
- Michael Jones
- Michał Kowieski
- Michał Łępicki
- Michele Riva
- Mike Lapping
- Mike Roach
- Milad
- Milton Mazzarri
- Nathaniel Knight
- Nick Reynolds
- Nicklas Sindlev Andersen
- NineFX
- OldhamMade
- Ole Michaelis
- Oliver Searle-Barnes
- Parker Selbert
- Pete Jodo
- phaleth
- porkbrain
- Praveen Perera
- qingliangcn
- Quinn Wilton
- Raúl Chouza
- Redmar Kerkhoff
- Reio Piller
- Reto Kramer
- Robin Mattheussen
- Ryan Winchester
- Sam Aaron
- Sascha Wolf
- Saša Jurić
- Scott Wey
- Sean Jensen-Grey
- Sebastian Porto
- Shane Sveller
- Shunji Lin
- Shuqian Hon
- silicium14
- Simone Vittori
- SkunkWerks GmbH
- SmartLogic
- Strand Communications
- Terje Bakken
- Tim Buchwaldt
- Tomasz Kowal
- Tomochika Hara
- Tristan de Cacqueray
- Tristan Sloughter
- tynanbe
- Uku Taht
- Victor Hugo Borja
- Vincent Le Goff
- Vladimir Kuznetsov
- WeiZheng Liu
- Wilson Silva
- Wojtek Mach
- YourMother-really
- Yt
- Yu Matsuzawa
Thanks for reading! Happy hacking! 💜