Erlang/OTP 29

This release of Erlang/OTP can be built from source, installed using pre-built packages for your OS or third-party tools (such as kerl, asdf or mise), or run from the official Docker image:

docker run -it erlang:29

Erlang/OTP 29 highlight blog post

New language features

  • Native records have been implemented as per EEP 79. They are a true data type rather than a tuple in disguise, and are considered experimental in Erlang/OTP 29 and possibly in Erlang/OTP 30 as well.
  • Multi-valued comprehensions have been implemented as per EEP 78, so that each iteration can contribute more than one element.
  • The new guard BIF is_integer/3 tests that a term is an integer within a range, following the design of EEP-16 with is_between renamed.
  • Function application is now left associative, so f(X)(Y) can be written instead of (f(X))(Y).
  • Matching in a comprehension qualifier used to compile and then fail at runtime, and is now rejected at compile time. The new compr_assign feature makes P = E behave as the strict generator P <-:- [E] instead.

Compiler and JIT improvements

  • The JIT generates better code for matching and creating binaries with multiple little-endian segments.
  • The compiler generates more efficient code for map comprehensions whose values do not depend on the generator.
  • Functions can be marked with the new -unsafe attribute, which is separate from deprecation: it says the function is unsafe to use at all, and calls to those in Erlang/OTP are warned about by default.
  • There are new warnings for exporting a variable out of a subexpression, for the catch operator, for matches that unify constructors, and, with the warn_obsolete_bool_op option, for the and and or operators.
  • The old-style type tests in guards (integer, atom and so on) have been scheduled for removal in Erlang/OTP 30.
  • The compile documentation has a new section with recommendations for implementors of languages running on the BEAM.

ERTS

  • In the default code path, the current working directory (.) is now last rather than first.
  • Iteration order over maps remains undefined, but is now guaranteed to be the same for every way of iterating over the same map.
  • The runtime system can generate encrypted crash dumps, enabled with --enable-encrypted-crash-dumps when building Erlang/OTP.
  • socket supports recvmmsg() and sendmmsg().
  • There is no longer a 32-bit Erlang/OTP build for Windows.

STDLIB

  • graph is a new module, a functional equivalent of digraph and digraph_utils.
  • io_ansi is a new module for emitting virtual terminal (ANSI) sequences. It reads the terminfo database of the terminal being written to, including across nodes, so a remote shell session renders correctly.
  • erl_tar streams entries to disk in chunks rather than reading each one into memory, and the new {max_size,Size} option limits the total extracted size.
  • array has several new functions. Its internal representation changed to allow them, so arrays serialised by earlier releases with term_to_binary/1 cannot be read back.
  • json decodes long strings up to 55% faster, and string:length/1 and string:slice/2,3 can be up to twice as fast.
  • rand:shuffle/1 and rand:shuffle_s/2 return a random permutation of a list.

common_test

  • ct_doctest is a new module for testing the examples in module documentation and documentation files, including examples that are meant to fail.

tools

  • xref applies the ignore_xref attribute itself rather than leaving it to build tools, and can find calls to functions that are undocumented, marked -doc false, or marked unsafe.

ssh

  • The daemon no longer enables the shell and exec services by default, so an authenticated user cannot execute arbitrary Erlang code unless it is asked for.
  • The SFTP subsystem is likewise no longer enabled by default.
  • The default key exchange algorithm is now mlkem768x25519-sha256, a hybrid combining ML-KEM-768 with X25519, falling back automatically for peers that do not support it.

Public Key / SSL / Inets

  • The post-quantum hybrid x25519mlkem768 is now the most preferred key exchange group, and ML-DSA and SLH-DSA the most preferred signature algorithms where such a certificate is configured. All of them were available in Erlang/OTP 28.4, but none were preferred.
  • There are new hardening guides for ssl and for inets.

Deprecations

  • The odbc application is deprecated and planned for removal in Erlang/OTP 30.
  • The ftp and ct_ftp modules are deprecated and planned for removal in Erlang/OTP 30.