It has been two months since the last one, so now it’s time for another Gleam release! Let’s see what’s new this time:

Improved error messages

Since the last release we’ve put a lot of work into the error messages emitted by the compiler. The most common and arguably the most important type of error is the type error, so we want it to be as clear and as friendly as possible.

Here’s what it looks like with Gleam v0.7:

This is a big improvement over previous versions which would struggle with highlighting multi-line code sections, and would state the problem as being Int != Float rather than List(Int) != List(Float) .

Other improved error messages include the import cycle error message:

Error messages for invalid patterns in case expressions:

And a slew of error messages relating to errors when trying to read or write files in a Gleam project.

Gleam aims to be an exceptionally friendly and productive language, so error messages are important. If there are any errors that you find confusing or unclear please get in touch and let us know!

In adding these new error messages we discovered a bug in rebar3 where unicode characters would be printed incorrectly in some circumstances. This bug is now fixed now but if you find your errors look incorrect please try upgrading your rebar3 version by running rebar3 local upgrade .

Alternative patterns

Sometimes when writing case expressions we want multiple different clauses to be able to trigger the same clause with different shaped data. To meet this need we’re introducing alternative patterns, separated by the | operator.

In this case expression the first clause will match if the variable number holds 2, 4, 6 or 8.

case number { 2 | 4 | 6 | 8 -> "This is an even number" 1 | 3 | 5 | 7 -> "This is an odd number" _ -> "I'm not sure" }

Clause guards

Sometimes when pattern matching we want to assert that two variables have the same value. Before this release we’d need to nested case expressions, now we have clause guards.

case xs { [ a , b ] if a == b -> "Two equal elements" [ a , b ] if a != b -> "Two unequal elements" _ other -> "Something else" }

Named sub-patterns

Sometimes when pattern matching we want to assign a name to a value while specifying it’s shape at the same time. With this release we can now do this using the as keyword.

case xs { [[ _ , _ ] as inner_list ] -> inner_list other -> [] }

Type aliases

Sometimes it can be tiring writing long type names in function annotations such as Result(List(tuple(String, String)), Nil) , often we’d rather write a short alias instead such as Option(Headers) . With type aliases this is now possible.

pub type Option ( value ) = Result ( value , Nil ) pub type Headers = List ( tuple ( String , String )) pub fn headers () -> Option ( Headers ) { Ok ([ tuple ( "x-served-by" , "Gleam" )]) }

The Option(value) alias above is often pretty useful! If you want to use it it is defined in the gleam/result module of the Gleam standard library.

Windows support

The Gleam compiler’s test suite is now running successfully on Windows, and a Windows binary is being compiled for new releases. If you’re developing on Windows please do give it a try and let us know of any problems you encounter.

The rest

In addition to these changes there’s been a bunch of bug fixes, performance improvements, and refactorings to the compiler. Please see the changelog for more detail.

If you want to try out the new version of Gleam head over to the installation page. I’d love to hear how you find it and get your feedback so Gleam can continue to improve.

Want to view some existing Gleam projects? Head on over to the awesome-gleam list. Looking for something to build in Gleam? Check out the suggestions tracker.

Thanks

Lastly, a huge thank you to the contributors to and sponsors of Gleam since last release!

If you would like to help make strongly typed programming on the Erlang virtual machine a production-ready reality please consider sponsoring Gleam via the GitHub Sponsors program.

Thanks for reading! Have fun! 💜