The Wayback Machine - https://web.archive.org/web/20241122235158/https://gleam.run/news/supercharged-labels/

Gleam is a type safe and scalable language for the Erlang virtual machine and JavaScript runtimes. Today Gleam v1.4.0 has been published, so let’s go over all that’s new.

A shorthand syntax for labels

Gleam’s labelled arguments are a way to give a parameter a name that can be used at the call site. These serve as documentation and to make code easier to read and modify. Here the function date takes 3 labelled arguments, day, month, and year.

pub fn main() {
  let day = 11
  let month = October
  let year = 1998
  date(year: year, month: month, day: day)
}

It’s relatively common in Gleam programs to have this repetition of a label and a variable with the same name. The new label shorthand means that the variable name can be omitted if it matches the name of the variable to be supplied. With this the above would be written like so:

pub fn main() {
  let day = 11
  let month = October
  let year = 1998
  date(year:, month:, day:)
}

The shorthand can be used for labelled record fields and in pattern matching too.

pub fn get_year(date: Date) -> Year {
  let Date(year:, ..) = date
  year
}

Label shorthand code action

There is also a new language server code-action (an automated code edit you can trigger in your editor) to convert to the shorthand syntax.

// Before
case date {
  Day(day: day, month: month, year: year) -> todo
}
// After
case date {
  Day(day:, month:, year:) -> todo
}

Thank you Giacomo Cavalieri for these features!

Adding labels action

The second code action in this release is one to automatically add the labels that a call accepts.

// Before
pub fn main() {
  Date()
}
// After
pub fn main() {
  Date(year: todo, month: todo, day: todo)
}

And now the programmer can replace the todo expressions with whatever values are appropriate, and they didn’t have to refer to the documentation to remember what the labels are. Thanks Giacomo Cavalieri once again!

Label access completion

And lastly on the label front, Ameen Radwan has added support for completion of labelled record fields.

Type a dot (.) after a record and the language server will suggest the fields you can access on the record, along with their types. Labels will also be suggested when when writing a function call or record construction that has labels.

Completions are now sorted by priority based on why the completion is in the list. This means that more specific completions like labels and local definitions will be shown before more broad completions like functions from a not yet imported module.

Thank you Ameen!

Signature help

The Gleam language server now implemented signature help. This means that when you’re calling a function your editor will display the documentation for the function as well as highlight which argument you need to supply next.

A picture is worth a thousand words, so presumably a video is a small book. Here’s a demonstration:

Thank you Giacomo Cavalieri for this!

Unmistakable warnings

The Gleam build tool implements incremental compilation, so a module will only be recompiled if its definition changes. This means that Gleam compile times stay low even as codebases grow very large.

One problem with the implementation was that if a module emitted a warning during compilation it would not be printed during future compilation unless the module was edited, as it would be cached instead. This could result in people not realising that their project has warnings as nothing was displayed when they run gleam build or gleam test.

Warnings are now emitted each time the project is built, ensuring that this mistake can no longer happen.

And on the topic of warnings, Damir Vandic has improved our Erlang typespec generation to silence new warnings that were added to Erlang in version OTP27. Thank you!

Targeted documentation

gleam docs build now takes an optional --target flag to specify the target platform for the generated documentation. This typically is not needed but if you use the discouraged conditional compilation features then it may be useful for your project. Thank you Jiangda Wang!

Even more fault tolerance!

Gleam’s compiler implements fault tolerant analysis. This means that when there is some error in the code that means it is invalid and cannot be compiled, the compiler can still continue to analyse the code to the best of its ability, ignoring the invalid parts. Because of this Gleam language server can have a good understanding of the code and provide IDE feature even when the codebase is in an invalid state.

Our language server magician Ameen Radwan has continued to improve this capability and now the compiler retains more information in the presence of record accessor or function call related errors, giving you a better experience in your text editor.

Help for a common type definition mistake

This is Gleam’s syntax for defining a type named User that has a single constructor also named User:

pub type User {
  User(name: String)
}

This syntax is similar to the class syntax in some object oriented languages where you define the class and constructors for the class for it within it.

One common mistake is to try and use a C-style struct definition syntax in Gleam, but this syntax is invalid.

pub type User {
  name: String
}

If you do this then the compile will now emit a custom error that show you what the correct syntax is and how to fix the problem:

error: Syntax error
  ┌─ /src/parse/error.gleam:3:5
  │
3 │     name: String,
  │     ^^^^ I was not expecting this

Each custom type variant must have a constructor:

pub type User {
  User(
    name: String,
  )
}

Thank you Rahul D. Ghosal for this feature!

A similar improved error message is emitted for when trying to use a function in a guard expression, while due to its Erlang heritage only a constant-time subset of pure expressions are permitted in guards. Thank you Thomas!

Constant concatenation

The <> string concatenation operator can now be used in constant expressions.

pub const greeting = "Hello"

pub const name = "Joe"

pub const sentence = greeting <> " " <> name <> "!"

Thank you again Thomas!

More JavaScript bit array support

Gleam has a literal syntax for constructing and pattern matching on bit arrays, providing a convenient and easier to understand alternative using bitwise operations, as is common in other languages. Currently not all options supported on the Erlang target are supported on the JavaScript target.

In this release Richard Viney has added support for the little and big endianness options, the signed and unsigned int options, 32-bit and 64-bit sized float options, and utf8 option. Thank you Richard!

Document symbols

The language server now supports listing document symbols, such as functions and constants, for the current Gleam file. You may use this in your editor to help you get a high-level overview of a module, or to help you navigate around a large file. This was added by PgBiel, thank you!

Case correction

Gleam uses snake_case for variables and functions, and PascalCase for types and record constructors. Using a different case is a compile error, so you’ll never have an argument about which case to use in Gleam!

In the event you accidentally use the wrong one the language server now suggests a code a action to automatically adjust the case to be correct.

// Before
let myNumber = 10
// After
let my_number = 10

Thank you Surya Rose for this feature!

Assert to case

The final code action, also from Surya Rose is one to convert a let assert expression into a semantically equivalent case and panic expression.

// Before
let assert Ok(value) = get_result()
// After
let value = case get_result() {
  Ok(value) -> value
  _ -> panic
}

Thank you Surya!

And the rest

An extra special shout out to the bug hunters Ameen Radwan, Connor Szczepaniak, Giacomo Cavalieri, Juraj Petráš, PgBiel, sobolevn, and Surya Rose! You stars!

If you’d like to see all the changes for this release, including all the bug fixes, check out the changelog in the git repository.

A call for support

Gleam has no corporate backing and is entirely supported by individuals, most of which contributing between $5 and $20 USD per month. I am fantastically grateful for your support, thank you so much.

I currently earn 32% the median salary tech lead salary for the UK, substantially less than I earned before I dedicated all my time to Gleam.

If you appreciate Gleam, please support the project on GitHub Sponsors with any amount you comfortably can.

Thanks for reading, I hope you have fun with Gleam! 💜

Try Gleam