Elixir v1.16.0 released

Official announcement: Elixir v1.16 released - The Elixir programming language

1. Enhancements


  • [EEx] Include relative file information in diagnostics


  • [Code] Add :emit_warnings for Code.string_to_quoted/2
  • [Code] Automatically include columns in parsing options
  • [Code] Introduce MismatchedDelimiterError for handling mismatched delimiter exceptions
  • [Code.Fragment] Handle anonymous calls in fragments
  • [Code.Formatter] Trim trailing whitespace on heredocs with \r\n
  • [File] Add :offset option to File.stream!/2
  • [Kernel] Auto infer size of matched variable in bitstrings
  • [Kernel] Preserve column information when translating typespecs
  • [Kernel] Suggest module names based on suffix and casing errors when the module does not exist in UndefinedFunctionError
  • [Kernel.ParallelCompiler] Introduce Kernel.ParallelCompiler.pmap/2 to compile multiple additional entries in parallel
  • [Kernel.SpecialForms] Warn if True/False/Nil are used as aliases and there is no such alias
  • [Macro] Add Macro.compile_apply/4
  • [Module] Add support for @nifs annotation from Erlang/OTP 25
  • [Module] Add support for missing @dialyzer configuration
  • [String] Update to Unicode 15.1.0
  • [String] Add String.replace_invalid/2
  • [Task] Add :limit option to Task.yield_many/2


  • [Logger] Add Logger.levels/0


  • [mix] Add MIX_PROFILE to profile a list of comma separated tasks
  • [mix archive.install] Support --sparse option
  • [mix compile.app] Warn if both :applications and :extra_applications are used
  • [mix compile.elixir] Pass original exception down to diagnostic :details when possible
  • [mix compile.elixir] Optimize scenario where there are thousands of files in lib/ and one of them is changed
  • [mix deps.clean] Emit a warning instead of crashing when a dependency cannot be removed
  • [mix escript.install] Support --sparse option
  • [mix release] Include include/ directory in releases
  • [mix test] Allow testing multiple file:line at once, such as mix test test/foo_test.exs:13 test/bar_test.exs:27

2. Bug fixes


  • [Code] Keep quotes for atom keys in formatter
  • [Code.Fragment] Fix crash in Code.Fragment.surround_context/2 when matching on ->
  • [IO] Raise when using IO.binwrite/2 on terminated device (mirroring IO.write/2)
  • [Kernel] Do not expand aliases recursively (the alias stored in Macro.Env is already expanded)
  • [Kernel] Ensure dbg module is a compile-time dependency
  • [Kernel] Warn when a private function or macro uses unquote/1 and the function/macro itself is unused
  • [Kernel] Re-enabled compiler optimizations for top level functions in scripts (disabled in v1.14.0 but shouldn’t impact most programs)
  • [Kernel] Do not define an alias for nested modules starting with Elixir. in their definition
  • [Kernel.ParallelCompiler] Consider a module has been defined in @after_compile callbacks to avoid deadlocks
  • [Macro] Address exception on Macro.to_string/1 for certain ASTs
  • [Path] Lazily evaluate File.cwd!/0 in Path.expand/1 and Path.absname/1
  • [Path] Ensure Path.relative_to/2 returns a relative path when the given argument does not share a common prefix with cwd


  • [ExUnit] Raise on incorrectly dedented doctests


  • [IEx.Pry] Fix prying functions with only literals in their body


  • [mix archive.install] Restore code paths after mix archive.install
  • [mix compile] Ensure files with duplicate modules are recompiled whenever any of the files change
  • [mix compile] Update Mix compiler diagnostics documentation and typespecs to match the Elixir compiler behaviour where both lines and columns start from one (before it inaccurately said that columns started from zero)
  • [mix escript.install] Restore code paths after mix escript.install

3. Soft deprecations (no warnings emitted)


  • [File] Deprecate File.stream!(file, options, line_or_bytes) in favor of keeping the options as last argument, as in File.stream!(file, line_or_bytes, options)
  • [Kernel.ParallelCompiler] Deprecate Kernel.ParallelCompiler.async/1 in favor of Kernel.ParallelCompiler.pmap/2
  • [Path] Deprecate Path.safe_relative_to/2 in favor of Path.safe_relative/2


  • [mix compile] Returning a four-element tuple as a position in Mix.Task.Compiler.Diagnostic

4. Hard deprecations


  • [Date] Deprecate inferring a range with negative step, call Date.range/3 with a negative step instead
  • [Enum] Deprecate passing a range with negative step on Enum.slice/2, give first..last//1 instead
  • [Kernel] ~R/.../ is deprecated in favor of ~r/.../. This is because ~R/.../ still allowed escape codes, which did not fit the definition of uppercase sigils
  • [String] Deprecate passing a range with negative step on String.slice/2, give first..last//1 instead


  • [ExUnit.Formatter] Deprecate format_time/2, use format_times/1 instead


  • [mix compile.leex] Require :leex to be added as a compiler to run the leex compiler
  • [mix compile.yecc] Require :yecc to be added as a compiler to run the yecc compiler

I know y’all get this a lot but… Thank You :pray:


Thank you everyone involved, this looks like a huge release for dev QOL.


Legendary! :smiley:


Great release. I especially appreciate the work of putting the anti-patterns guides together and keeping them with the language docs. That’s such a game changer to me. It’s essentially a small book with elixir anti-patterns and solutions, only it will be kept up-to-date by the community. Of course thanks also goes to the researchers, having it in the official docs gives it a whole lot more visibility and authority though. Well done, team.

I just happily sent a link to a friend of mine who is working with elixir their first time and DM’ed me some weeks back going “Tobi, is it normal in elixir that there are like 16 clauses for functions all matching on things doing entirely different things?!?!?!” - so sending them the “unrelated multi clause function” doc now was great :grin: (and hopefully helps convince their colleagues more than “my friend Tobi said”).


:pray: :pray: :pray: :clap: :clap: :clap: :christmas_tree: :partying_face: :tada:

1 Like

Apologies for not trying out the RC but holy heck are these new errors ever nice. Thanks, Elixir folks!


Does Phoenix 1.7.10 support for Elixir 1.16 ?

I haven’t tried it but I’d be shocked if it doesn’t, elixir is always very stable and backwards compatible. Officially it’s " requires Elixir v1.11+" so I’m rather confident. There’s also no open issues or MRs relating to the topic.

I just noticed it’s not tested against though, so I’ll PR that :slight_smile: