Julia v1.12 Release Notes
New language features
- New experimental option
--trimthat creates smaller binaries by removing code not proven to be reachable from entry points. Entry points can be marked usingBase.Experimental.entrypoint(#55047). Not all code is expected to work with this option, and since it is experimental you may encounter problems. - Redefinition of constants is now well defined and follows world age semantics (#57253). Additional redefinitions (e.g. of types) are now allowed. See the new manual chapter on world age.
- A new keyword argument
usings::Boolhas been added tonames, returning all names visible viausing(#54609). - The
@atomicmacro family now supports reference assignment syntax, e.g.@atomic :monotonic v[3] += 4, which modifiesv[3]atomically with monotonic ordering semantics (#54707). The supported syntax allows- atomic fetch (
x = @atomic v[3]), - atomic set (
@atomic v[3] = 4), - atomic modify (
@atomic v[3] += 2), - atomic set once (
@atomiconce v[3] = 2), - atomic swap (
x = @atomicswap v[3] = 2), and - atomic replace (
x = @atomicreplace v[3] 2=>5).
- atomic fetch (
- New option
--task-metrics=yesto enable the collection of per-task timing information, which can also be enabled/disabled at runtime withBase.Experimental.task_metrics(::Bool)(#56320). The available metrics are:- actual running time for the task (
Base.Experimental.task_running_time_ns), and - wall-time for the task (
Base.Experimental.task_wall_time_ns).
- actual running time for the task (
- Support for Unicode 16 (#56925).
Threads.@spawnnow takes a:samepoolargument to specify the same threadpool as the caller.Threads.@spawn :samepool foo()which is shorthand forThreads.@spawn Threads.threadpool() foo()(#57109).- The
@ccallmacro can now take agc_safeargument, that if set to true allows the runtime to run garbage collection concurrently to theccall(#49933).
Language changes
- When a method is replaced with an exactly equivalent one, the old method is not deleted. Instead, the new method takes priority and becomes more specific than the old method. Thus if the new method is deleted later, the old method will resume operating. This can be useful in mocking frameworks (as in SparseArrays, Pluto, and Mocking, among others), as they do not need to explicitly restore the old method. At this time, inference and compilation must be repeated in this situation, but we may eventually be able to re-use the old results (#53415).
- Macro expansion will no longer eagerly recurse into
Expr(:toplevel)expressions returned from macros. Instead, macro expansion of:toplevelexpressions will be delayed until evaluation time. This allows a later expression within a given:toplevelexpression to make use of macros defined earlier in the same:toplevelexpression (#53515). - Trivial infinite loops (like
while true; end) are no longer undefined behavior. Infinite loops that do things (e.g. have side effects or sleep) were never and are still not undefined behavior (#52999). - It is now an error to mark a binding as both
publicandexported (#53664). - Errors during
getfieldnow raise a newFieldErrorexception type instead of the genericErrorException(#54504). - Macros in function-signature-position no longer require parentheses. E.g.
function @main(args) ... endis now permitted, whereasfunction (@main)(args) ... endwas required in prior Julia versions. - Calling
usingon a package name inside of that package of that name (especially relevant for a submodule) now explicitly uses that package without examining the Manifest and environment, which is identical to the behavior of..Name. This appears to better match how users expect this to behave in the wild (#57727).
Compiler/Runtime improvements
- Generated LLVM IR now uses pointer types instead of passing pointers as integers. This affects
llvmcall: Inline LLVM IR should be updated to usei8*orptrinstead ofi32ori64, and remove unneededptrtoint/inttoptrconversions. For compatibility, IR with integer pointers is still supported, but generates a deprecation warning (#53687).
Command-line option changes
- The
-m/--moduleflag can be passed to run themainfunction inside a package with a set of arguments. Thismainfunction should be declared using@mainto indicate that it is an entry point (#52103). - Enabling or disabling color text in Julia can now be controlled with the
NO_COLORorFORCE_COLORenvironment variables. These variables are also honored by Julia's build system (#53742, #56346). --project=@tempstarts Julia with a temporary environment (#51149).- New
--trace-compile-timingoption to report how long each method reported by--trace-compiletook to compile, in ms (#54662). --trace-compilenow prints recompiled methods in yellow or with a trailing comment if color is not supported (#55763).- New
--trace-dispatchoption to report methods that are dynamically dispatched (#55848).
Multi-threading changes
- Julia now defaults to 1 "interactive" thread, in addition to the 1 default "worker" thread. i.e.
-t1,1. This means in default configuration the main task and repl (when in interactive mode), which both run on thread 1, now run within theinteractivethreadpool. The libuv IO loop also runs on thread 1, helping efficient utilization of the worker threadpool used byThreads.@spawn. Asking for specifically 1 thread (-t1/JULIA_NUM_THREADS=1) or0interactive threads will disable the interactive thread i.e.-t1,0orJULIA_NUM_THREADS=1,0, or-tauto,0etc. Asking for more than 1 thread will enable the interactive thread so-t2will set the equivalent of-t2,1. As a reminder, buffers should not be managed based onthreadid()(#57087). - New types are defined to handle the pattern of code that must run once per process, called a
OncePerProcess{T}type, which allows defining a function that should be run exactly once the first time it is called, and then always return the same result value of typeTevery subsequent time afterwards. There are alsoOncePerThread{T}andOncePerTask{T}types for similar usage with threads or tasks (#55793).
Build system changes
- There are new
Makefiles to build Julia and LLVM using the Binary Optimization and Layout Tool (BOLT). Seecontrib/boltandcontrib/pgo-lto-bolt(#54107).
New library functions
logrange(start, stop; length)makes a range of constant ratio, instead of constant step (#39071).- The new
isfull(c::Channel)function can be used to check ifput!(c, some_value)will block (#53159). waitany(tasks; throw=false)andwaitall(tasks; failfast=false, throw=false)which wait for multiple tasks at once (#53341).uuid7()creates an RFC 9562 compliant UUID with version 7 (#54834).insertdims(array; dims)inserts singleton dimensions into an array –- the inverse operation ofdropdims(#45793).- A new
Fixtype generalizesFix1/Fix2for fixing a single argument (#54653). Sys.detectwsl()tests whether Julia is running inside WSL at runtime (#57069).
New library features
escape_stringtakes additional keyword argumentsascii=true(to escape all non-ASCII characters) andfullhex=true(to require full 4/8-digit hex numbers for u/U escapes, e.g. for C compatibility) (#55099).tempnamecan now take a suffix string to allow the file name to include a suffix and include that suffix in the uniquing checking (#53474).RegexMatchobjects can now be used to constructNamedTuples andDicts (#50988).Lockableis now exported (#54595).Base.require_one_based_indexingandBase.has_offset_axesare now public (#56196).- New
ltruncate,rtruncateandctruncatefunctions for truncating strings to text width, accounting for char widths (#55351). isless(and thuscmp, sorting, etc.) is now supported for zero-dimensionalAbstractArrays (#55772).invokenow supports passing aMethodinstead of a type signature (#56692).invokenow supports passing aCodeInstanceinstead of a type, which can enable certain compiler plugin workflows (#56660).Timer(f, ...)will now match the stickiness of the parent task when creating timer tasks, which can be overridden by the newspawnkeyword argument. This avoids the issue where sticky tasks (i.e.@async) make their parent sticky (#56745).Timernow has readabletimeoutandintervalproperties, and a more descriptiveshowmethod (#57081).sortnow supportsNTuples (#54494).map!(f, A)now stores the results inA, likemap!(f, A, A)orA .= f.(A)(#40632).setprecisionwith a function argument (typically adoblock) is now thread safe. Other forms should be avoided, and types should switch to an implementation usingScopedValue(#51362).
Standard library changes
gcdx(0, 0)now returns(0, 0, 0)instead of(0, 1, 0)(#40989).fdreturns aRawFDinstead of anInt(#55080).
JuliaSyntaxHighlighting
- A new standard library for applying syntax highlighting to Julia code, this uses
JuliaSyntaxandStyledStringsto implement ahighlightfunction that creates anAnnotatedStringwith syntax highlighting applied (#51810).
LinearAlgebra
rankcan now take aQRPivotedmatrix to allow rank estimation via QR factorization (#54283).- Added keyword argument
algtoeigen,eigen!,eigvalsandeigvals!for self-adjoint matrix types (i.e., the type unionRealHermSymComplexHerm) that allows one to switch between different eigendecomposition algorithms (#49355). - Added a generic version of the (unblocked) pivoted Cholesky decomposition (callable via
cholesky[!](A, RowMaximum())) (#54619). - The number of default BLAS threads now respects process affinity, instead of using the total number of logical threads available on the system (#55574).
- A new function
zeroslikeis added that generates the zero elements for matrix-valued banded matrices. Custom array types may specialize this function to return an appropriate result (#55252). - The matrix multiplication
A * Bcallsmatprod_dest(A, B, T::Type)to generate the destination. This function is now public (#55537). - The function
haszero(T::Type)is used to check if a typeThas a unique zero element defined aszero(T). This is now public (#56223). - A new function
diagviewis added that returns a view into a specific band of anAbstractMatrix(#56175).
Profile
Profile.take_heap_snapshottakes a new keyword argument,redact_data::Bool, which istrueby default. When set, the contents of Julia objects are not emitted in the heap snapshot. This currently only applies to strings (#55326).Profile.print()now colors Base/Core/Package modules similarly to how they are in stacktraces. Also paths, even if truncated, are now clickable in terminals that support URI links to take you to the specifiedJULIA_EDITORfor the given file & line number (#55335).
REPL
- Using the new
usings=truefeature of thenames()function, REPL completions can now complete names visible viausing(#54610). - REPL completions can now complete input lines like
[import|using] Mod: xxx|e.g. completeusing Base.Experimental: @optousing Base.Experimental: @opaque(#54719). - The REPL will now warn if it detects a name is being accessed via a module which does not define it (nor has a submodule which defines it), and for which the name is not public in that module. For example,
mapis defined in Base, and executingLinearAlgebra.mapin the REPL will now issue a warning the first time it occurs (#54872). - When the result of a REPL input is printed, the output is now truncated to 20 KiB. This does not affect manual calls to
show,print, etc. (#53959). - Backslash completions now print the respective glyph or emoji next to each matching backslash shortcode (#54800).
Test
- A failing
DefaultTestSetnow prints to screen the random number generator (RNG) of the failed test, to help reproducing a stochastic failure which only depends on the state of the RNG. It is also possible seed a test set by passing therngkeyword argument to@testset:using Test, Random @testset rng=Xoshiro(0x2e026445595ed28e, 0x07bb81ac4c54926d, 0x83d7d70843e8bad6, 0xdbef927d150af80b, 0xdbf91ddf2534f850) begin @test rand() == 0.559472630416976 end
InteractiveUtils
- New macros
@trace_compileand@trace_dispatchfor running an expression with--trace-compile=stderr --trace-compile-timingand--trace-dispatch=stderrrespectively enabled (#55915).
External dependencies
- The terminal info database,
terminfo, is now vendored by default, providing a better REPL user experience whenterminfois not available on the system. Julia can be built without vendoring the database using the Makefile optionWITH_TERMINFO=0(#55411).
Tooling Improvements
- A wall-time profiler is now available for users who need a sampling profiler that captures tasks regardless of their scheduling or running state. This type of profiler enables profiling of I/O-heavy tasks and helps detect areas of heavy contention in the system (#55889).