Julia v1.14 Release Notes
New language features
It is now possible to control which version of the Julia syntax will be used to parse a package by setting the
compat.juliaorsyntax.julia_versionkey in Project.toml. This feature is similar to the notion of "editions" in other language ecosystems and will allow non-breaking evolution of Julia syntax in future versions. See the "Syntax Versioning" section in the code loading documentation (#60018).ᵅ(U+U+1D45),ᵋ(U+1D4B),ᶲ(U+1DB2),˱(U+02F1),˲(U+02F2), andₔ(U+2094) can now also be used as operator suffixes, accessible as\^alpha,\^epsilon,\^ltphi,\_<,\_>, and\_schwaat the REPL (#60285).The
@labelmacro can now create labeled blocks that can be exited early withbreak name [value]. Use@label name exprfor named blocks or@label exprfor anonymous blocks. Anonymous@labelblocks participate in the default break scope: a plainbreakorbreak _exits the innermost breakable scope, whether it is a loop or an@labelblock. Thecontinuestatement also supports labels withcontinue nameto continue a labeled loop (#60481).typegroupblocks allow defining mutually recursive struct types that reference each other in their field types. All types in the group are resolved atomically at the end of the block (#60569).
Language changes
Type{T} <: Snow holds only if every type==toTis an instance ofS, fixing a long-standing soundness hole where e.g.Type{Int} <: DataTypeheld even though types likeTuple{S} where S<:Intare==(andisa) their canonical spelling without beingDataTypes. In particularType{T}is no longer a subtype of any single kind: use a union of kinds instead (e.g.Type{Int} <: Union{DataType,UnionAll}holds).isaand dispatch of type values are unaffected, and a method onType{Int}remains more specific than one onDataType(#33136, #62141).Introduced explicitly wrapping arithmetic operators
+%,-%,*%to annotate arithmetic operations that are semantically safe to wrap/overflow. Their behavior is currently identical to the default+,-,*operators. However, in a future version, there may be opt-in support to detect unannotated wrapping in the default operators (#50790).
Compiler/Runtime improvements
Type inference now refines field types through conditional checks and call signatures. For example, after
if !isnothing(x.field), inference knowsx.fieldis notnothingwithin the branch. Similarly, after a call likefunc(x.field)wherefunc(::Int)is the only matching method, inference refinesx.fieldtoInt. This works for immutable struct fields andconstfields of mutable structs. Mutable (non-const) fields are not supported due to the lack of per-object memory effect tracking; for those, the recommended pattern remains storing the field value in a local variable before the check (e.g.val = x.field; if !isnothing(val) ... end) (#41199, #47574).Stack traces now show full method signatures with argument types for inlined frames, matching the display of non-inlined frames (#53925).
Parallel package precompilation now coordinates CPU usage across both the precompile worker processes and the LLVM threads each spawns to compile its native image, sharing a single thread budget so idle cores are filled during the long tail without oversubscribing the machine when many packages compile at once. The total budget can be set with the new
JULIA_PRECOMPILE_THREADSenvironment variable (#61958).
Command-line option changes
-P <project>is now a shorthand for--project <project>(#59867).
Multi-threading changes
New functions
Threads.atomic_fence_heavyandThreads.atomic_fence_lightprovide support for asymmetric atomic fences, speeding up atomic synchronization where one side of the synchronization runs significantly less often than the other (#60311).Threads.@threadsnow supports array comprehensions with syntax like@threads [f(i) for i in 1:n], filtered comprehensions like@threads [f(i) for i in 1:n if condition(i)], typed comprehensions like@threads Float64[f(i) for i in 1:n], and multi-dimensional comprehensions like@threads [f(i,j) for i in 1:n, j in 1:m](preserves dimensions). All scheduling options (:static,:dynamic,:greedy) are supported. Results preserve element order for:staticand:dynamicscheduling;:greedydoes not guarantee order. Non-indexable iterators are also supported. (#59019)The task scheduler now avoids O(nthreads) wake overhead on every
@spawn, significantly reducing threading overhead particularly on highly oversubscribed machines. Benchmarks show up to 1000x reduction in spawn time in such scenarios (#61826).
Build system changes
New library functions
tap(f)creates a function that callsf(x)for side effects and returnsx. (#61340).Base.set_binding_visibility!sets the declared visibility (:none,:public, or:export) of a name in a module, allowing anexportorpublicdeclaration to be retracted programmatically (#62131).Base.generating_output()has been madepublic(but not exported) to allow checking whether the current process is performing compilation for a pkgimage/sysimage (#61224).
Base.raw_substringis an unexported, public constructor to build aSubStringwithout checking for valid string indices.Base.unannotate(::AnnotatedString)returns the underlying un-annotated string of the input string.Base.include_mapexprs(mod)is an unexported, public function returning the non-identitymapexprfunctions used byinclude(mapexpr, …)calls while loading the package rooted atmod, keyed by(including_module, absolute_path). The table is stored inside the package image, so it survives precompilation; revision tools (e.g. Revise) use it to re-apply the original transform when aninclude(mapexpr, …)-ed file is edited.
New library features
IOContextsupports a new booleanhexunsignedoption that allows for printing unsigned integers in decimal instead of hexadecimal (#60267).lazy"..."strings now support a flaglazy"..."cthat addscompactandlimitflags to theIOContextfor final output-string generation (#61887).The
StringViewtype wraps anAbstractVector{UInt8}and interprets it as a UTF-8 encoded string, superseding the StringViews.jl package (#60526).Package precompilation now supports running precompilation in a background task and has new interactive keyboard controls:
cto cleanly cancel immediately,dto detach,ifor a profile peek,vto toggle verbose mode showing elapsed time, CPU%, and memory usage, and?for help. (#60943).Instances of an
Enumcan now be given their own docstrings within the@enumdefinition (#61955).New methods
readdir(path, DirEntry)andreaddir(::DirEntry, DirEntry)return directory contents along with the type of the entries in a vector of newDirEntryobjects to provide more efficientisfileetc. checks.readdir(::DirEntry)accepts aDirEntryas input and, likereaddir(::AbstractString), returns aVector{String}of names.DirEntryis exported fromBase(#55358).
Standard library changes
codepoint(c)now succeeds for overlong encodings.Base.ismalformed,Base.isoverlong, andBase.show_invalidare nowpublicand documented (but not exported) (#55152).
JuliaSyntaxHighlighting
LinearAlgebra
Markdown
Support "raw" or "inline" HTML inside Markdown data (#60629, #60632, #60732)
Support autolinks for email addresses (#60570)
Many improvements and bugfixes for rendering Markdown lists in a terminal (#55456, #60519)
Strikethrough text via
~strike~or~~through~~is now supported by the Markdown parser. (#60537)Many, many bug fixes and minor tweaks; overall behavior is now much closer to CommonMark (#59977, #60502)
Profile
Random
REPL
Test
@test,@test_throws, and@test_brokennow support acontextkeyword argument that provides additional information displayed on test failure. This is useful for debugging which specific case failed in parameterized tests (#60501).@test_throws,@test_warn,@test_nowarn,@test_logs, and@test_deprecatednow supportbrokenandskipkeyword arguments for consistency with@test(#60543).New functions
detect_closure_boxesanddetect_closure_boxes_allfind methods that allocateCore.Boxin their lowered code, which can indicate performance issues from captured variables in closures.
Dates
unix2datetimenow accepts a keyword argumentlocaltime=trueto use the host system's local time zone instead of UTC (#50296).
InteractiveUtils
less/@lessandedit/@editare now supported for documented variables (#53539).