Elixir is a dynamic, functional language for building scalable and maintainable applications
Code.string_to_quoted/2
honors :static_atoms_encoder
for multi-letter sigilscapture_log
capture_log
callspry
works on Erlang/OTP 25 and earlier while IEx is bootingCode.Fragment.surround_context
considers surround context around spaces and parens:function
as metadata--werl
from release scripts on Erlang/OTP 26Official announcement: https://elixir-lang.org/blog/2023/06/19/elixir-v1-15-0-released/
%s
) to Calendar.strftime/2
Code.format_string!/2
now converts 'charlists'
into ~c"charlists"
by default:on_undefined_variable
to the compiler options to preserve the warning behaviour which was deprecated back in Elixir v1.4Code.loaded?/1
and Code.ensure_all_loaded(!)/1
Code.prepend_paths/1
, Code.append_paths/1
, and Code.delete_paths/1
Code.with_diagnostics/2
to return diagnostics when compiling and evaluating codeCode.Fragment.cursor_context/1
Code.Fragment.container_cursor_to_quoted/1
Date.before?/2
and Date.after?/2
DateTime.before?/2
and DateTime.after?/2
DateTime.utc_now/2
File.Stream
Inspect
now renders 'charlists'
as ~c"charlists"
by defaultcase
and cond
inside dbg/2
t:nonempty_binary/0
and t:nonempty_bitstring/0
@behaviour
s as runtime dependencieserror: ...
messages, similar to warning: ...
Code.compiler_options(on_undefined_variable: :warn)
at the top of your mix.exs
--sname undefined
/--name undefined
so a name is automatically generatedKeyword.split_with/2
Macro.Env.lookup_alias_as/2
Map.split_with/2
Map.intersect/2
and Map.intersect/3
MapSet.split_with/2
NaiveDateTime.beginning_of_day/1
and NaiveDateTime.end_of_day/1
NaiveDateTime.before?/2
and NaiveDateTime.after?/2
NaiveDateTime.utc_now/2
Module.get_last_attribute/3
:return_separator
optionProcess.alias/0,1
and Process.unalias/1
Range.split/2
:fast_ascii
mode to String.valid?/2
Supervisor
:lines
in System.cmd/3
to capture output line by lineTask.yield_many/2
Task.Supervisor.start_child/2
Time.before?/2
and Time.after?/2
URI.append_path/2
{module, function}
tuples in ExUnit setup
callbacksExUnit.Case.get_last_registered_test/1
ExUnit.DocTest.doctest_file/2
doctest_data
in doctest tags--dbg pry
IEX_HOME
alias
, import
, and require
runtime_info(:allocators)
Range
, DateTime
, and Regex
Logger.add_handlers/1
and Logger.default_formatter/1
default_formatter
and default_handler
configuration for Logger which configures Erlang/OTP logger:always_evaluate_messages
configuration to Logger:start_concurrently
configuration--all-warnings
by default@external_resources
optional_applications
to .app
file--purge-consolidation-path-if-stale
which will purge the given consolidation path if compilation is requiredmix deps.get
/mix deps.update
--check-locked
which raises if changes to the lockfile are required--no-exit
option--check-formatted
fails--trace-to-file
to improve performance when working with large outputseval
command--output
flagdef cli
to unify all CLI defaults in a single placeMix.Project.deps_tree/1
Exception.blame/3
File.cp/2
File.rm_rf/1
try/rescue
...
inside typespecsbehaviour_info
and module_info
functions from Erlang modulesModule.get_attribute/3
returns nil
and not the given default value when an attribute has been explicitly set as nil
System.stop/1
executesURI.merge/2
works accordingly with relative paths@tag capture_log: true
was set to true and the Logger application was shut down in the middle of the testsetup_all
cwd
in compiler cache keyerlsrv.exe
in path with spacesmix xref
is used at the umbrella rootFile.cp/3
and File.cp_r/3
with a function as third argument
is deprecated in favor of a keyword list:return_diagnostics
option to be
set to true when compiling or requiring codeadd_backend/2
, remove_backend/2
, and configure_backend/2
have been deprecated
in favor of the new :logger_backends
dependency:console
configuration has been deprecated in favor of :default_formatter
:backends
configuration has been deprecated in favor of Logger.add_handlers/1
:preferred_cli_env
is deprecated in favor of :preferred_envs
in def cli
:preferred_cli_target
is deprecated in favor of :preferred_targets
in def cli
HEX_MIRROR
is deprecated in favor of HEX_BUILDS_URL
Calendar.ISO.day_of_week/3
is deprecated in favor of Calendar.ISO.day_of_week/4
Exception.exception?/1
is deprecated in favor of Kernel.is_exception/1
...
as a valid function call identifierRegex.regex?/1
is deprecated in favor of Kernel.is_struct/2
Logger.warn/2
is deprecated in favor of Logger.warning/2
Note this release includes offline Elixir installers for Windows per supported Erlang/OTP version.
doctest_data
in doctest tagsimport m, only: :sigils
for multi-letter sigils (regression)Macro.to_string/1
for multi-letter sigils (regression)setup_all
mix xref
is used at the umbrella rootFile.Stream
Module.get_last_attribute/3
ExUnit.Case.get_last_registered_test/1
:on_undefined_variable
option works as advertised (regression)Code.with_diagnostic/2
as relative paths (regression)Module.get_attribute/3
returns nil
and not the given default value when an attribute has been explicitly set as nil
included_applications
can be loaded (regression)This release requires Erlang/OTP 24 and later.
Elixir v1.15 is a smaller release with focused improvements on compilation and boot times. This release also completes our integration process with Erlang/OTP logger, bringing new features such as log rotation and compaction out of the box.
You will also find additional convenience functions in Code
,
Map
, Keyword
, all Calendar modules, and others.
The last several releases brought improvements to compilation time and this version is no different. In particular, Elixir now caches and prunes load paths before compilation, ensuring your project (and dependencies!) compile faster and in an environment closer to production.
In a nutshell the Erlang VM loads modules from code paths. Each application that ships with Erlang and Elixir plus each dependency become an entry in your code path. The larger the code path, the more work Erlang has to do in order to find a module.
In previous versions, Mix would only add entries to the load paths.
Therefore, if you compiled 20 dependencies and you went to compile
the 21st, the code path would have 21 entries (plus all Erlang and
Elixir apps). This allowed modules from unrelated dependencies to
be seen and made compilation slower the more dependencies you had.
With this release, we will now prune the code paths to only the ones
listed as dependencies, bringing the behaviour closer to mix release
.
Furthermore, Erlang/OTP 26 allows us to start applications
concurrently and cache the code path lookups, decreasing the cost of
booting applications. The combination of Elixir v1.15 and Erlang/OTP 26
should reduce the boot time of applications, such as when starting
iex -S mix
or running a single test with mix test
, from 5% to 30%.
The compiler is also smarter in several ways: @behaviour
declarations
no longer add compile-time dependencies and aliases in patterns and
guards add no dependency whatsoever, as no dispatching happens. Furthermore,
Mix now tracks the digests of @external_resource
files, reducing the
amount of recompilation when swapping branches. Finally, dependencies
are automatically recompiled when their compile-time configuration changes.
Due to the code path pruning, if you have an application or dependency
that does not specify its dependencies on Erlang and Elixir application,
it may no longer compile successfully in Elixir v1.15. You can temporarily
disable code path pruning by setting prune_code_paths: false
in your
mix.exs
, although doing so may lead to runtime bugs that are only
manifested inside a mix release
.
The Elixir compiler can now emit many errors for a single file, making sure more feedback is reported to developers before compilation is aborted.
In Elixir v1.14, an undefined function would be reported as:
** (CompileError) undefined function foo/0 (there is no such import)
my_file.exs:1
In Elixir v1.15, the new reports will look like:
error: undefined function foo/0 (there is no such import)
my_file.exs:1
** (CompileError) nofile: cannot compile file (errors have been logged)
A new function, called Code.with_diagnostics/2
, has been added so this
information can be leveraged by editors, allowing them to point to several
errors at once.
This release provides additional features such as global logger metadata and file logging (with rotation and compaction) out-of-the-box!
This release also soft-deprecates Elixir's Logger Backends in
favor of Erlang's Logger handlers. Elixir will automatically
convert your :console
backend configuration into the new
configuration. Previously, you would set:
config :logger, :console,
level: :error,
format: "$time $message $metadata"
Which is now translated to the equivalent:
config :logger, :default_handler,
level: :error
config :logger, :default_formatter,
format: "$time $message $metadata"
If you use Logger.Backends.Console
or other backends, they are
still fully supported and functional. If you implement your own
backends, you want to consider migrating to
:logger_backends
in the long term.
See the new Logger
documentation for more information on the
new features and on compatibility.
%s
) to Calendar.strftime/2
Code.format_string!/2
now converts 'charlists'
into ~c"charlists"
by default:on_undefined_variable
to the compiler options to preserve the warning behaviour which was deprecated back in Elixir v1.4Code.loaded?/1
and Code.ensure_all_loaded(!)/1
Code.prepend_paths/1
, Code.append_paths/1
, and Code.delete_paths/1
Code.with_diagnostics/2
to return diagnostics when compiling and evaluating codeCode.Fragment.cursor_context/1
Code.Fragment.container_cursor_to_quoted/1
Date.before?/2
and Date.after?/2
DateTime.before?/2
and DateTime.after?/2
DateTime.utc_now/2
Inspect
now renders 'charlists'
as ~c"charlists"
by defaultcase
and cond
inside dbg/2
t:nonempty_binary/0
and t:nonempty_bitstring/0
@behaviour
s as runtime dependencieserror: ...
messages, similar to warning: ...
--sname undefined
/--name undefined
so a name is automatically generatedKeyword.split_with/2
Macro.Env.lookup_alias_as/2
Map.split_with/2
Map.intersect/2
and Map.intersect/3
MapSet.split_with/2
NaiveDateTime.beginning_of_day/1
and NaiveDateTime.end_of_day/1
NaiveDateTime.before?/2
and NaiveDateTime.after?/2
NaiveDateTime.utc_now/2
:return_separator
optionProcess.alias/0,1
and Process.unalias/1
Range.split/2
:fast_ascii
mode to String.valid?/2
Supervisor
:lines
in System.cmd/3
to capture output line by lineTask.yield_many/2
Task.Supervisor.start_child/2
Time.before?/2
and Time.after?/2
URI.append_path/2
{module, function}
tuples in ExUnit setup
callbacksExUnit.DocTest.doctest_file/2
--dbg pry
IEX_HOME
alias
, import
, and require
runtime_info(:allocators)
Range
, DateTime
, and Regex
Logger.add_handlers/1
and Logger.default_formatter/1
default_formatter
and default_handler
configuration for Logger which configures Erlang/OTP logger:always_evaluate_messages
configuration to Logger:start_concurrently
configuration--all-warnings
by default@external_resources
optional_applications
to .app
file--purge-consolidation-path-if-stale
which will purge the given consolidation path if compilation is requiredmix deps.get
/mix deps.update
--check-locked
which raises if changes to the lockfile are required--no-exit
option--check-formatted
fails--trace-to-file
to improve performance when working with large outputseval
command--output
flagdef cli
to unify all CLI defaults in a single placeMix.Project.deps_tree/1
Exception.blame/3
File.cp/2
File.rm_rf/1
try/rescue
...
inside typespecsbehaviour_info
and module_info
functions from Erlang modulesSystem.stop/1
executesURI.merge/2
works accordingly with relative paths@tag capture_log: true
was set to true and the Logger application was shut down in the middle of the testcwd
in compiler cache keyerlsrv.exe
in path with spacesFile.cp/3
and File.cp_r/3
with a function as third argument
is deprecated in favor of a keyword list:return_diagnostics
option to be
set to true when compiling or requiring codeadd_backend/2
, remove_backend/2
, and configure_backend/2
have been deprecated
in favor of the new :logger_backends
dependency:console
configuration has been deprecated in favor of :default_formatter
:backends
configuration has been deprecated in favor of Logger.add_handlers/1
:preferred_cli_env
is deprecated in favor of :preferred_envs
in def cli
:preferred_cli_target
is deprecated in favor of :preferred_targets
in def cli
HEX_MIRROR
is deprecated in favor of HEX_BUILDS_URL
Calendar.ISO.day_of_week/3
is deprecated in favor of Calendar.ISO.day_of_week/4
Exception.exception?/1
is deprecated in favor of Kernel.is_exception/1
...
as a valid function call identifierRegex.regex?/1
is deprecated in favor of Kernel.is_struct/2
Logger.warn/2
is deprecated in favor of Logger.warning/2
This release adds basic support for Erlang/OTP 26. When migrating
to Erlang/OTP 26, keep it mind it changes how maps are stored
internally and they will be printed and traversed in a different
order (note maps never provided a guarantee of their order).
To aid migration, this release adds :sort_maps
to inspect
custom options, in case you want to sort them before inspection:
inspect(map, custom_options: [sort_maps: true])
:sort_maps
to Inspect.Opts.custom_options
Code.quoted_to_string_with_comments/2
debug_info/4
when returning core_v1quote keep: true
to avoid invalid stacktracesStream.zip/1
hanging on empty listCalendar.strftime/2
is_struct/2
guardsdefguard
expansiondefmodule
Macro.to_string/1
for large negative integers__ENV__
in macrosPath.wildcard/2
expands ..
symlinks accordinglyRange.disjoint?/2
implementationCode.eval_quoted_with_env/4
with support for the :prune_binding
option:doctest
and :doctest_line
as meta tagsExUnit.Formatter.format_assertion_diff/4
Mix.install/2
accepts atoms as pathssize*unit
shortcut in bitstringdefguard
:for
in protocols with the appropriate envExUnit.run/1