Published 16 Apr, 2024 by Louis Pilfold
Gleam is a type safe and scalable language for the Erlang virtual machine and JavaScript runtimes. Today Gleam v1.1.0 has been published, just a month after v1.0.0. There’s loads of new stuff in this release, so take a look at some of what’s new!
Language server improvements
Productivity and developer experience is a first class concern to us, and in a modern language good editor support is an important part of the puzzle. To help Gleam has a built-in language server which is developed and maintained by the core team. The language server is relatively immature compared to the rest of the language’s tooling, and it is one of the main focuses for core development at the moment.
It has been improved in these ways:
Compilation batching
The language server is driven by messages sent by your editor each time a file is opened, code is edited, autocompletions are needed, and so on. When messages are received the language server runs the compiler (minus the codegen sections) to get information about the code.
The language server now batches theses messages intelligently, compiling when required rather than on every message. For example, if your editor rapidly sends several text edits and then a request for refactorings the language server will now apply all the edits to its in-memory filesystem overlay before compiling a single time. If you are using a faster computer you likely will see no difference, but if you’re using a slower computer or in a very large project you’ll no longer experience a delay before getting feedback from the language server.
Autocomplete imports
The language server will now autocomplete module names when writing import statements. Thank you Ameen Radwan for this improvement!
Global goto definition
Gleam’s language server previously supported go-to definition for values defined in the top-level package, but with this release it also works for values defined in dependency packages too. Thank you Ameen Radwan again!
Bun support
Gleam compiles to JavaScript as well as Erlang, and there are multiple popular options for running JavaScript code on the command line. Gleam supports the NodeJS and Deno runtimes, and with v1.1.0 Bun support has been added too!
To use Bun either add javascript.runtime
key to your gleam.toml
, or add
the --runtime=bun
flag to your gleam run
or gleam test
command.
name = "app"
version = "1.0.0"
target = "javascript"
[javascript]
runtime = "bun"
Thank you gubsey for this feature.
Rebar support
Rebar3 is the standard Erlang build tool but some projects use the older build tool rebar (without the 3). Rebar3 has some amount of backwards compatibility with rebar and can build a typical rebar project, so with this release Gleam will now use rebar3 to build any rebar packages added as dependencies. This is enough to use all rebar packages we’ve found on the package manager so far.
Thank you Isaac Harris-Holt for this feature!
Formatter improvements
Giacomo Cavalieri the pretty-printing wizard has been hard at work improving the formatter and fixing bugs. One highlight is that the formatter will now sort groups of imports into alphabetical order automatically.
Juho Eerola also improved support for non-\n
newlines in the formatter, causing them to be converted to \n
rather than
discarding them, which previously resulted in some empty lines being removed.
Clearer dependency requirements
Gleam uses the Hex package manager, and Hex specifies a syntax for version
constraints. The syntax ~> 1.0
, which means >= 1.0.0 and <
2.0.0
, and Gleam would use this in your gleam.toml
when adding a dependency
with gleam add
.
This syntax was very commonly misunderstood by people, and often would be
confused for the ~> 1.0.0
syntax, which looks very similar but does something
different and undesirable. To avoid this repeated confusion the longer and
easier to understand syntax is now used instead.
JavaScript list optimisation
Julian Schurhammer identified and implemented an optimisation for prepending to a list on the JavaScript target. List prepending is extremely common in Gleam, so optimisations here have a big impact. Once applied running the standard library test suite went from ~3.0 seconds to ~2.4 seconds. Thank you Julian!
# before
2.98s user 0.37s system 135% cpu 2.471 total
2.85s user 0.37s system 133% cpu 2.409 total
3.00s user 0.39s system 134% cpu 2.516 total
# after
2.37s user 0.35s system 132% cpu 2.048 total
2.33s user 0.37s system 134% cpu 2.009 total
2.38s user 0.36s system 134% cpu 2.034 total
Internal types and values
Gleam has a concept of internal modules, which are modules that are only to be
used from within the same package. With this release the @internal
attribute can
be used to make a type or value internal in a module that is otherwise
not-internal. This may be helpful for exposing functionality so that it can be
directly tested, while not making it part of the package’s public API.
Thank you Giacomo Cavalieri for this feature!
Dead code elimination
Gleam packages can be cross-target and work on both Erlang and JavaScript. These packages may have target specific dependencies which are only used on one target or the other.
The compiler now performs more aggressive dead-code elimination and will remove any code that is unreachable for the target that is currently being used.
Better package validation
Since v1.0.0 the number of Gleam packages has really taken off, new ones being published every day.
We don’t just want a healthy number of packages, we also want to ensure that Gleam packages are as high quality as possible. With this release we have some more things that we will be checking packages for before publishing, to catch common mistakes.
The gleam.toml
project file includes the location of the source code
repository for the package. Sometimes folks would make typos or forget to make
the repository public, making the documentation’s links there unusable. When
publishing Gleam will now make a request to this URL to ensure it loads
successfully.
The Hex package manager has rules against name squatting, and empty packages published to reserve a name may be removed. Gleam now checks to make sure that blank packages are not published, and warns the publisher this is against the Hex terms of service.
Improved diagnostics
Gleam’s warnings and errors try to be as helpful as possible, hopefully making it clear how your code can be improved. Several improved error messages and new warnings have been added:
A case
expression in Gleam can pattern match on multiple subjects at once.
Folks may not be aware of this and may instead wrap multiple values in a redundant
tuple as would be required in some other languages. This now causes a warning to
be emitted:
In a future release the language server will have a code-action to remove this for you.
Another new warning is this one that is emitted when a literal expression or a
side-effect free expression is not used. This helps the programmer catch dead
code, and possibly also identify problems such as the missing <>
in the
example here:
And lastly, an example of an improved error. One mistake people unfamiliar with immutable linked lists might make is to attempt to append to a list using the list syntax. This syntax only works for prepending as prepending is fast, while appending is slow.
Thank you Giacomo Cavalieri for these improvements!
Improved tuple parsing
Tuples can be indexed into using the .0
, .1
, .2
, etc syntax, but with
previous versions of the parser indexing into nested tuples like tuple.0.2
would not parse successfully. Thank you to Nikita Sobolev
for fixing this problem!
And the rest
That’s enough for this post, but there’s lots more. If you’d like to see all the changes for this release check out the changelog in the git repository.
Thanks
Gleam is made possible by the support of all the kind people and companies who have very generously sponsored or contributed to the project. Thank you all!
If you like Gleam consider sponsoring or asking your employer to sponsor Gleam development. I work full time on Gleam and your kind sponsorship is how I pay my bills!
Alternatively consider using our referral link for CodeCrafters, who have recently launched a course on implementing Redis in Gleam. Use your training budget to learn and to support Gleam too!
- 0fie
- 0riginaln0
- Aaron Gunderson
- Abdulrhman Alkhodiry
- ad-ops
- Adam Brodzinski
- Adam Johnston
- Adi Iyengar
- Aiden Fox Ivey
- Airradda
- Ajit Krishna
- aldrin-ronco
- Alembic
- Alex Manning
- Alexander Koutmos
- Alexander Stensrud
- Alexandre Del Vecchio
- Alivy
- Ameen Radwan
- AndreHogberg
- Andrew Kachnic
- André Mazoni
- Andy Aylward
- Anthony Bullard
- Anthony Khong
- Anthony Scotti
- Arnaud Berthomier
- Arnav K
- Artem Solomatin
- Arthur Weagel
- Austin Miller
- Avraam “Makis” Marimpis
- Barry Moore
- Ben Marx
- Ben Myles
- Benjamin Peinhardt
- Benjamin Thomas
- Bill Nunney
- Brad Lewis
- Bram Vanbilsen
- Brett Cannon
- brettkolodny
- Brian Corbin
- Brian Dawn
- Brian Glusman
- Bruno Michel
- bucsi
- bwireman
- Carlo Munguia
- Carlos Saltos
- catapillie
- Chad Selph
- Charlie Govea
- Chaz Watkins
- Chen Tao
- Chew Choon Keat
- Chris Birster
- Chris Donnelly
- Chris King
- Chris Lloyd
- Chris Ohk
- Chris Rybicki
- Christopher Dieringer
- Christopher Keele
- clangley
- Clay
- Cleo
- CodeCrafters
- Coder
- Cole Lawrence
- Colin
- Comamoca
- Cristine Guadelupe
- Damir Vandic
- Dan Dresselhaus
- Daniel
- Danielle Maywood
- Danik Vitek
- Danny Arnold
- Danny Martini
- darenc
- Darshak Parikh
- Dave Lucia
- David Bernheisel
- David Flanagan
- David Legrand
- David Sancho
- Dennis Dang
- dennistruemper
- dependabot[bot]
- desk7
- Dezhi Wu
- Dhuds1
- Dillon Mulroy
- Dimitrii Dulgher
- Divya Jain
- Dmitry Poroh
- Dmytro Utkin
- domnantas
- ds2600
- Edon Gashi
- eli
- Elie Labeca
- Elliott Pogue
- Emma
- EMR Technical Solutions
- Endercheif
- Erik Lilja
- Erik Terpstra
- ErikML
- Ernesto Malave
- F. Schwalbe
- Felix Mayer
- Fernando Farias
- Filip Figiel
- Fionn Langhans
- fitv
- Florian Kraft
- fly.io
- Georg H. Ekeberg
- Giacomo Cavalieri
- Graeme Coupar
- grotto
- gubsey
- Guilherme de Maio
- Guillaume Hivert
- Hamir Mahal
- Hammad Javed
- Hampus Kraft
- Hannes Schnaitter
- Hayes Hundman
- Hayleigh Thompson
- Hazel Bachrach
- Henning Dahlheim
- Henry Firth
- Henry Warren
- Hex
- human154
- Humberto Piaia
- Ian Gonzalez
- Igor Rumiha
- Ikko Eltociear Ashimine
- inoas
- Isaac Adewumi
- Isaac Harris-Holt
- Ismael Abreu
- Ivar Vong
- Iztok Fister Jr
- J. Rinaldi
- Jacob Fenton
- Jacob Lamb
- James Birtles
- James MacAulay
- Jan Skriver Sørensen
- Jaxon Carelos
- Jean-Luc Geering
- Jean-Nicolas Veigel
- Jen Stehlik
- jiangplus
- Jimpjorps™
- Jiri Luzny
- Joey Kilpatrick
- Johan Strand
- John Björk
- John Pavlick
- Jonas Hedman Engström
- Josef Richter
- Josh
- Josh Gillies
- Joshua Steele
- Juho Eerola
- Julian Schurhammer
- Kero van Gelder
- Kieran Gill
- kodumbeats
- Kramer Hampton
- Kryštof Řezáč
- Krzysztof G.
- Lars Wikman
- Larz Conwell
- Leandro Ostera
- Leon Qadirie
- lidashuang
- LighghtEeloo
- Loïc Tosser
- Lucian Petic
- Léopold Hubert
- Manuel Jesús de la Fuente
- Manuel Rubio
- Marcøs
- Mariano Uvalle
- Marius Kalvø
- Mark Holmes
- Mark Jaquith
- Mark Markaryan
- Marshall Bowers
- Martin Janiczek
- Martin Rechsteiner
- Matt Champagne
- Matt Savoia
- Matt Van Horn
- Matthias Benkort
- Max
- Max McDonnell
- max-tern
- Maxime Bouillot
- Michael Davis
- Michael Duffy
- Michael Jones
- Michael Kieran O’Reilly
- Michael Kumm
- Mike Roach
- Moshe Goldberg
- MzRyuKa
- n8n - Workflow Automation
- Nashwan Azhari
- Natanael Sirqueira
- Nathaniel Knight
- Nayuki
- NFIBrokerage
- Nick Chapman
- Nick Reynolds
- Nicklas Sindlev Andersen
- Nikita Arkhipov
- Nikita Sobolev
- NineFX
- Nomio
- Ocean Armstrong Lewis
- OldhamMade
- Ole Michaelis
- optizio
- Patrick Wheeler
- Paul Gideon Dann
- Paul Guse
- Pawel Biernacki
- Pedro Pires
- Pete Jodo
- Peter
- Peter Rice
- Peter Saxton
- PgBiel
- Philip Giuliani
- Piotr Szlachciak
- Prashant Singh Pawar
- qingliangcn
- Race Williams
- racerole
- Rahim
- Rahul Butani
- Rasmus
- Raúl Chouza
- Redmar Kerkhoff
- Ricardo
- Ricardo Fernández Serrata
- Richard Viney
- Rico Leuthold
- Robert Attard
- Robert Ellen
- Robert Malko
- Roberto Trevisan
- Robson Gian Perassoli
- Ross Bratton
- Ross Cousens
- Sam Aaron
- Sami Fouad
- Sammy Isseyegh
- Samu
- Samuel Burkhardt
- Santi Lertsumran
- sarna
- Satoshi Yoshikawa
- Saša Jurić
- Scott Patten
- Scott Trinh
- Scott Wey
- Sean Jensen-Grey
- Sebastian
- sekun
- Sergei Suvorov
- Seve Salazar
- Shane Handley
- Shaun McCarthy
- Shuqian Hon
- Sidney Millen
- Simon Curtis
- Simone Vittori
- Siraj
- Skenvy
- star-szr
- Szymon Wygnański
- Sławomir Ehlert
- Theo Harris
- Thomas
- Tim Heaney
- Tim Morgner
- Timm Friebe
- Timo Sulg
- Tomasz Kowal
- trag1c
- Tristan Cacqueray
- Tristan Sloughter
- veryyet
- Vic Valenzuela
- Victor Rodrigues
- victorybhg
- Viv Verner
- Vladimir Kidyaev
- Vladislav Botvin
- Volker Rabe
- Weizheng Liu
- Wesley Moore
- wgancar
- Willyboar
- Xavier Drdak
- Xavier Noria
- xhh
- Yamen Sader
- Yaroslav Lapin
- Yasuo Higano
- Yu Matsuzawa
- zahash
- Zsombor Gasparin
- Šárka Slavětínská
Thanks for reading, and I hope you enjoy Gleam v1 💜