Julia v1.9 Release Notes
New language features
- It is now possible to assign to bindings in another module using
setproperty!(::Module, ::Symbol, x)
(#44137) (#44231). - Slurping in assignments is now also allowed in non-final position. This is handled via
Base.split_rest
(#42902). - Character literals now support the same syntax allowed in string literals; i.e. the syntax can represent invalid UTF-8 sequences as allowed by the
Char
type (#44989). - Support for Unicode 15 (#47392).
- Nested combinations of tuples and named tuples of symbols are now allowed as type parameters (#46300).
- New builtins
getglobal(::Module, ::Symbol[, order])
andsetglobal!(::Module, ::Symbol, x[, order])
for reading from and writing to globals.getglobal
should now be preferred for accessing globals overgetfield
(#44137) (#44231).
Language changes
- The
@invoke
macro introduced in 1.7 is now exported. Additionally, it now usesCore.Typeof(x)
rather thanAny
when a type annotation is omitted for an argumentx
so that types passed as arguments are handled correctly (#45807). - The
invokelatest
function and@invokelatest
macro introduced in 1.7 are now exported (#45831).
Compiler/Runtime improvements
- Time to first execution (TTFX, sometimes called time to first plot) is greatly reduced. Package precompilation now saves native code into a "pkgimage", meaning that code generated during the precompilation process will not require compilation after package load. Use of pkgimages can be disabled via
--pkgimages=no
(#44527) (#47184). - The known quadratic behavior of type inference is now fixed and inference uses less memory in general. Certain edge cases with auto-generated long functions (e.g. ModelingToolkit.jl with partial differential equations and large causal models) should see significant compile-time improvements (#45276, #45404).
- Non-concrete call sites can now be union-split to be inlined or statically resolved even if there are multiple dispatch candidates. This may improve runtime performance in certain situations where object types are not fully known statically, by statically resolving
@nospecialize
-d call sites and avoiding excessive compilation (#44512). - All uses of the
@pure
macro inBase
have been replaced with the now-preferredBase.@assume_effects
(#44776). invoke(f, invokesig, args...)
calls to a less-specific method than would normally be chosen forf(args...)
are no longer spuriously invalidated when loading package precompile files (#46010).
Command-line option changes
- In Linux and Windows,
--threads=auto
now tries to infer the usable number of CPUs from the process affinity which is set typically in HPC and cloud environments (#42340). --math-mode=fast
is now a no-op (#41638). Users are encouraged to use the @fastmath macro instead, which has more well-defined semantics.- The
--threads
command-line option now acceptsauto|N[,auto|M]
whereM
specifies the number of interactive threads to create (auto
currently means 1) (#42302). - New option
--heap-size-hint=<size>
suggests a size limit to invoke garbage collection more eagerly. The size may be specified in bytes, kilobytes (1000k), megabytes (300M), or gigabytes (1.5G) (#45369).
Multi-threading changes
Threads.@spawn
now accepts an optional first argument::default
or:interactive
. An interactive task desires low latency and implicitly agrees to be short duration or to yield frequently. Interactive tasks will run on interactive threads, if any are specified when Julia is started (#42302).- Threads started outside the Julia runtime (e.g. from C or Java) can now become able to call into Julia code by calling
jl_adopt_thread
. This is done automatically when entering Julia code viacfunction
or a@ccallable
entry point. As a consequence, the number of threads can now change during execution (#46609).
Build system changes
New library functions
- New function
Iterators.flatmap
(#44792). - New
pkgversion(m::Module)
function to get the version of the package that loaded a given module, similar topkgdir(m::Module)
(#45607). - New function
stack(x)
which generalisesreduce(hcat, x::Vector{<:Vector})
to any dimensionality, and allows any iterator of iterators. Methodstack(f, x)
generalisesmapreduce(f, hcat, x)
and is more efficient (#43334). - New macro
@allocations
which is similar to@allocated
except reporting the total number of allocations rather than the total size of memory allocated (#47367).
New library features
RoundFromZero
now works for non-BigFloat
types (#41246).Dict
can be now shrunk manually bysizehint!
(#45004).@time
now separates out % time spent recompiling invalidated methods (#45015).
Standard library changes
- A known concurrency issue in
iterate
methods onDict
and other derived objects such askeys(::Dict)
,values(::Dict)
, andSet
is fixed. These methods ofiterate
can now be called on a dictionary or set shared by arbitrary tasks provided that there are no tasks mutating the dictionary or set (#44534). - Predicate function negation
!f
now returns a composed function(!) ∘ f
instead of an anonymous function (#44752). eachslice
now works over multiple dimensions;eachslice
,eachrow
andeachcol
return aSlices
object, which allows dispatching to provide more efficient methods (#32310).@kwdef
is now exported and added to the public API (#46273).- An issue with order of operations in
fld1
is now fixed (#28973). - Sorting is now always stable by default, as
QuickSort
was stabilized (#45222). Base.splat
is now exported. The return value is now aBase.Splat
instead of an anonymous function, which allows for pretty printing (#42717).
Package Manager
- "Package Extensions": support for loading a piece of code based on other packages being loaded in the Julia session. This has similar applications as the Requires.jl package but also supports precompilation and setting compatibility.
LinearAlgebra
- The methods
a / b
andb \ a
witha
a scalar andb
a vector, which were equivalent toa * pinv(b)
, have been removed due to the risk of confusion with elementwise division (#44358). - We are now wholly reliant on libblastrampoline (LBT) for calling BLAS and LAPACK. OpenBLAS is shipped by default, but building the system image with other BLAS/LAPACK libraries is not supported. Instead, it is recommended that the LBT mechanism be used for swapping BLAS/LAPACK with vendor provided ones (#44360).
lu
supports a new pivoting strategyRowNonZero()
that chooses the first non-zero pivot element, for use with new arithmetic types and for pedagogy (#44571).normalize(x, p=2)
now supports any normed vector spacex
, including scalars (#44925).- The default number of BLAS threads is now set to the number of CPU threads on ARM CPUs, and half the number of CPU threads on other architectures (#45412, #46085).
Printf
- Error messages for bad format strings have been improved, to make it clearer what and where in the format string is wrong (#45366).
Profile
- New function
Profile.take_heap_snapshot(file)
that writes a file in Chrome's JSON-based.heapsnapshot
format (#46862).
Random
randn
andrandexp
now work for anyAbstractFloat
type definingrand
(#44714).
REPL
Alt-e
now opens the current input in an editor. The content (if modified) will be executed upon exiting the editor (#33759).- The contextual module which is active in the REPL can be changed (it is
Main
by default), via theREPL.activate(::Module)
function or via typing the module in the REPL and pressing the keybinding Alt-m (#33872). - A "numbered prompt" mode which prints numbers for each input and output and stores evaluated results in
Out
can be activated withREPL.numbered_prompt!()
. See the manual for how to enable this at startup (#46474). - Tab completion displays available keyword arguments (#43536).
SuiteSparse
- Code for the SuiteSparse solver wrappers has been moved to SparseArrays.jl. Solvers are now re-exported by SuiteSparse.jl.
SparseArrays
- SuiteSparse solvers are now available as submodules of SparseArrays (https://github.com/JuliaSparse/SparseArrays.jl/pull/95).
- UMFPACK (https://github.com/JuliaSparse/SparseArrays.jl/pull/179) and CHOLMOD (https://github.com/JuliaSparse/SparseArrays.jl/pull/206) thread safety are improved by avoiding globals and using locks. Multithreaded
ldiv!
of UMFPACK objects may now be performed safely. - An experimental function
SparseArrays.allowscalar(::Bool)
allows scalar indexing of sparse arrays to be disabled or enabled. This function is intended to help find accidental scalar indexing ofSparseMatrixCSC
objects, which is a common source of performance issues (https://github.com/JuliaSparse/SparseArrays.jl/pull/200).
Test
- New fail-fast mode for testsets that will terminate the test run early if a failure or error occurs. Set either via the
@testset
kwargfailfast=true
or by setting env varJULIA_TEST_FAILFAST
to"true"
i.e. in CI runs to request the job failure be posted eagerly when issues occur (#45317)
Dates
- Empty strings are no longer incorrectly parsed as valid
DateTime
s,Date
s orTime
s and instead throw anArgumentError
in constructors andparse
, whilenothing
is returned bytryparse
(#47117).
Distributed
- The package environment (active project,
LOAD_PATH
,DEPOT_PATH
) is now propagated when adding local workers (e.g. withaddprocs(N::Int)
or through the--procs=N
command line flag) (#43270). addprocs
for local workers now accepts theenv
keyword argument for passing environment variables to worker processes. This was already supported for remote workers (#43270).
Unicode
graphemes(s, m:n)
returns a substring of them
-th ton
-th graphemes ins
(#44266).
DelimitedFiles
- DelimitedFiles has been moved out as a separate package.
Deprecated or removed
External dependencies
- On Linux, now autodetects the system libstdc++ version, and automatically loads the system library if it is newer. The old behavior of loading the bundled libstdc++ regardless of the system version can be restored by setting the environment variable
JULIA_PROBE_LIBSTDCXX=0
(#46976). - Removed
RPATH
from the julia binary. On Linux this may break libraries that have failed to setRUNPATH
.
Tooling Improvements
- Printing of
MethodError
and methods (such as frommethods(my_func)
) is now prettified and colored consistently with printing of methods in stacktraces (#45069).
Regressions
A list of known regressions in the v1.9 release can be found here