Published 01 Nov, 2023 by Louis Pilfold
Gleam is a type safe and scalable language for the Erlang virtual machine and JavaScript runtimes. Today Gleam v0.32.0 has been published, a release that focuses on getting Gleam ready for a v1.0 release by making some breaking changes before the language is declared stable.
Resolving import ambiguity
Here is what Gleam’s import syntax looks like:
import gleam/option.{Option, Some, None}
pub fn greet(option: Option(String)) -> String {
case option {
Some(name) -> "Hello " <> name
None -> "Hello, World!"
}
}
Here the module gleam/option
is being imported, and the values Some
, and
None
and the type Option
are being imported in an unqualified manner so
they can be referred to without the module_name.
prefix.
While Option
is a type and None
is a value they are both imported using the
same syntax. This becomes more complex when we consider that in Gleam a type and
a value can have the same name. For example:
/// A type called `Person`
pub type Person {
/// A value constructor, also called `Person`
Person(name: String)
}
In this case when you read the code import the/module.{Person}
you cannot tell
if the type is being imported, the value, or both. This ambiguity is resolved by
the compiler by checking to see how the imported item is used.
Clarity is a core goals of Gleam, so to ease the cognitive load of reading Gleam code the syntax for importing types and values has been altered.
import gleam/option.{type Option, Some, None}
To import a type the keyword type
is used before the name, no keyword being
used for a value. Now it is always clear what an import statement is doing!
The old syntax is still supported, but will be removed in a future release, and a deprecation warning will be emitted when it is used.
BitString -> BitArray
Gleam has a type for a contiguous sequence of bits. It is similar to Python’s
bytes
type, however it is not restricted to 8 bit bytes, it can be any number
of bits.
It also features a literal syntax for construction and pattern matching, so much of what you would need to use bitwise operations for in other languages can be done with a simpler syntax.
pub fn seven_bit_little_endian_int() -> BitString {
<<2:size(7)-little>>
}
This feature, which Gleam inherited from Erlang, is much loved by the community
except for the name. Many Gleam users, especially those coming from languages
other than Erlang or Elixir, find the name BitString
confusing. What does it
have to do with strings? It is for text only?
This confusion is understandable, and so the name has been changed to
BitArray
, and in the pattern syntax the binary
and bit_string
options have
been renamed to bytes
and bits
, hopefully making their purpose clearer.
Along with this the gleam/bit_string
standard library module has been
deprecated in favour of gleam/bit_array
. The old names and module are
deprecated and will be removed in a future release.
The return of gleam fix
Wow, that’s a lot of deprecated stuff! It’s going to be annoying to fix all the
existing code, right? Thankfully not, as the gleam fix
command is back.
Run gleam fix
in the root of any Gleam package and it will automatically
update your code to use the new syntax. It will also update the gleam.toml
file to set the Gleam version constraint to >= 0.32.0
, ensuring that if you
publish your package to the Hex package manager any users on older versions of
Gleam won’t get confusing errors coming from the new syntax.
Language server code actions
The gleam
binary includes the compiler, the build tool, the package manager,
and also the language server, which provides IDE features to VS Code, Vim,
Emacs, and any other edit which support the protocol.
With this release the language server gets its first code action! It can now automatically remove all unused imports with a single press of a button.
This is a nice convenience feature, but it also means that the language server internally has the infrastructure in place to add more code actions in future. User experience and productivity is highly important to us, so the language server will be getting more code actions and new features in future releases.
Thank you Tristan de Cacqueray for this feature!
Target specific gleam check
If during development you want to see whether your code type checks but don’t
care about compiling it to run your tests you can use the gleam check
command.
With this release it gains the --target
flag, allowing you to specify a
compilation target other than the default for the package. This is useful in
packages that use conditional compilation, a less common but sometimes necessary
Gleam feature.
Thank you Kunal Kundu for this feature!
Module access in guard expressions
Values defined in other modules can now be referenced in case clause guards
expressions using the module_name.value
syntax.
import some/module.{type Person}
pub fn greet(person: Person) -> String {
case person {
Person(name: n) if n == module.friends_name -> "Hey Buddy!"
_ -> "Hello! Welcome!"
}
}
Thank you Shayan Javani for this feature!
Bit array constants on the JavaScript target
Bit arrays can now be used in constant expressions on the JavaScript target.
pub const some_bits = <<1, 2, 3, 4>>
Thank you Shayan Javani for this feature!
@deprecated
types
The previous release added the @deprecated
attribute, which could be used to
mark values as deprecated. This release extends this to allow type definitions
to be marked as deprecated too.
@deprecated("Use the Pet type instead")
pub type Animal {
Cat
Dog
}
When a type is marked as deprecated the compiler will emit a warning when the type or any of its value constructors are referenced.
Thank you Om Prakaash for this feature!
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!
- Aaron Gunderson
- Adam Brodzinski
- Adam Mokan
- Adi Iyengar
- Adi Salimgereev
- Alembic
- Alex Manning
- Alexander Koutmos
- Alexander Stensrud
- Alexandre Del Vecchio
- Ali Farhadi
- Andy Aylward
- Anthony Khong
- Anthony Scotti
- Arnaud Berthomier
- Barry Moore
- Ben Marx
- Ben Myles
- Benjamin Peinhardt
- brettkolodny
- Brian Glusman
- Bruno Michel
- Carlo Gilmar
- Carlos Saltos
- Chew Choon Keat
- Chris Lloyd
- Chris Ohk
- Christopher Keele
- Christopher Rybicki
- clangley
- Clay
- Coder
- Cole Lawrence
- Colin
- Cosmo Shin (신의하)
- Cristine Guadelupe
- Damir Vandic
- Dan Dresselhaus
- Danielle Maywood
- Danny Martini
- Dave Lucia
- David Bernheisel
- David Flanagan
- David Sancho
- dependabot[bot]
- Dmitry Poroh
- Edon Gashi
- Elliott Pogue
- Emma
- Erik Terpstra
- Erika Rowland
- Ernesto Malave
- Fernando Farias
- Filip Figiel
- Florian Kraft
- fly.io
- Ganesh Gupta
- Gavin McGimpsey
- Giacomo Cavalieri
- Graeme Coupar
- Guilherme de Maio
- Gustavo Villa
- Harry Bairstow
- Hayleigh Thompson
- Hazel Bachrach
- Henry Warren
- Hex
- Ian González
- Ingmar Gagen
- inoas
- Ivar Vong
- James Birtles
- James MacAulay
- Jan Fooken
- Jan Skriver Sørensen
- Jechol Lee
- Jen Stehlik
- jiangplus
- Joey Kilpatrick
- John Björk
- John Gallagher
- John Palgut
- Jonas Hedman Engström
- Josef Richter
- Kayla Washburn
- Kieran Gill
- Kunal Kundu
- Lars Wikman
- Leon Qadirie
- lidashuang
- Manuel Rubio
- Marius Kalvø
- Mark Holmes
- Mark Markaryan
- Markus
- Martin Janiczek
- Matt Van Horn
- Matthias Benkort
- max-tern
- Michael Davis
- Michael Duffy
- Michael Jones
- Mike Roach
- Mikko Ahlroth
- Natanael Sirqueira
- Nathaniel Knight
- NFIBrokerage
- Nick Reynolds
- Nicklas Sindlev Andersen
- NicoVIII
- Nik Sidnev
- NineFX
- Noah Betzen
- Ocean Armstrong Lewis
- OldhamMade
- Ole Michaelis
- Om Prakaash
- Parker Selbert
- Paul Gideon Dann
- Pete Jodo
- Prashant Singh Pawar
- Praveen Perera
- qingliangcn
- Raúl Chouza
- Redmar Kerkhoff
- Rico Leuthold
- Robert Attard
- Robert Ellen
- Sam Aaron
- Sammy Isseyegh
- Saša Jurić
- Scott Wey
- Sean Jensen-Grey
- Sebastian Porto
- SEKUN
- Seve Salazar
- shayan javani
- Shuqian Hon
- Signal Insights
- Simone Vittori
- Stefan Luptak
- Szymon Wygnański
- Terje Bakken
- Theo Harris
- Timo Sulg
- Tomasz Kowal
- Tristan Cacqueray
- Tristan Sloughter
- Tyler
- Weizheng Liu
- Willyboar
- Wilson Silva
- Wojtek Mach
- Wolf
- Xetera
- Yasuo Higano
- Yu Matsuzawa
- Zsombor Gasparin
- Šárka Slavětínská
Thanks for reading! Happy hacking! 💜