The Compat package is designed to ease interoperability between
older and newer versions of the Julia
language. In particular, in cases where it is
impossible to write code that works with both the latest Julia
master
branch and older Julia versions, or impossible to write code
that doesn't generate a deprecation warning in some Julia version, the
Compat package provides a macro that lets you use the latest syntax
in a backwards-compatible way.
This is primarily intended for use by other Julia packages, where it is important to maintain cross-version compatibility.
To use Compat in your Julia package, add a line Compat
to the
REQUIRE
file in your package directory. Then, in your package,
shortly after the module
statement include lines like these:
using Compat
import Compat.String
and then as needed add
@compat ...compat syntax...
wherever you want to use syntax that differs in the latest Julia
master
(the development version of Julia). The compat syntax
is usually
the syntax on Julia master
. However, in a few cases where this is not possible,
a slightly different syntax might be used.
Please check the list below for the specific syntax you need.
Currently, the @compat
macro supports the following syntaxes:
-
@compat (a::B{T}){T}(c) = d
— the Julia 0.5-style call overload -
@compat(get(io, s, false))
, withs
equal to:limit
,:compact
or:multiline
, to detect the corresponding print settings (performs useful work only on Julia 0.5, defaults tofalse
otherwise) -
@compat Nullable(value, hasvalue)
to handle the switch from theNullable
:isnull
field to:hasvalue
field (#18510) -
@compat x .= y
converts to an in-place assignment tox
(viabroadcast!
) (#17510). However, beware that.=
in Julia 0.4 has the precedence of==
, not of assignment=
, so if the right-hand-sidey
includes expressions with lower precedence than==
you should enclose it in parenthesesx .= (y)
to ensure the correct order of evaluation. Also,x .+= y
converts tox .= (x .+ y)
, and similarly for the other updating assignment operators (.*=
and so on). -
@compat Array{<:Real}
,@compat Array{>:Int}
, and similar uses of<:T
(resp.>:T
) to define a set of "covariant" (resp. "contravariant") parameterized types (#20414). In 0.5, this only works for non-nested usages (e.g. you can't defineArray{<:Array{<:Real}}
). -
@compat abstract type T end
and@compat primitive type T 8 end
to declare abstract and primitive types. #20418 This only works when@compat
is applied directly on the declaration. -
@compat A{T} = B{T}
or@compat const A{T} = B{T}
to declare type alias with free parameters. #20500. Useconst A = B{T}
orconst A = B
for type alias without free parameters (i.e. no type parameter on the left hand side). -
@compat Base.IndexStyle(::Type{<:MyArray}) = IndexLinear()
and@compat Base.IndexStyle(::Type{<:MyArray}) = IndexCartesian()
to define traits for abstract arrays, replacing the formerBase.linearindexing{T<:MyArray}(::Type{T}) = Base.LinearFast()
andBase.linearindexing{T<:MyArray}(::Type{T}) = Base.LinearSlow()
, respectively. -
Compat.collect(A)
returns anArray
, no matter what indices the arrayA
has. #21257 -
@compat foo(::CartesianRange{N})
to replace the formerfoo(::CartesianRange{CartesianIndex{N}})
(#20974). Note thatCartesianRange
now has two type parameters, so using them as fields in otherstruct
s requires manual intervention. -
Required keyword arguments (#25830). For example,
@compat foo(; x, y)
makesx
andy
required keyword arguments: when callingfoo
, an error is thrown ifx
ory
is not explicitly provided.
-
using Compat.Test
,using Compat.SharedArrays
,using Compat.Mmap
, andusing Compat.DelimitedFiles
are provided on versions older than 0.7, where these are not yet part of the standard library. (#23931) -
using Compat.Base64
is provided on versions older than 0.7, where this library is not yet a part of the standard library. (#24361) -
using Compat.Dates
is provided on versions older than 0.7, where this library is not yet a part of the standard library. (#24459) -
using Compat.Unicode
is provided on versions older than 0.7, where this library is not yet a part of the standard library. (#25021) -
using Compat.Printf
is provided on versions older than 0.7, where this library is not yet a part of the standard library. (#25056) -
using Compat.SparseArrays
is provided on versions older than 0.7, where this library is not yet part of the standard library (#25249). -
using Compat.LinearAlgebra
is provided on versions older than 0.7, where this library is not yet part of the standard library (#25571). -
using Compat.Random
is provided on versions older than 0.7, where this library is not yet part of the standard library (#24874). -
using Compat.Libdl
is provided on versions older than 0.7, where this library is not yet part of the standard library (#25459). -
using Compat.REPL
is provided on versions older than 0.7, where this library is not yet part of the standard library (#25544). -
using Compat.Serialization
is provided on versions older than 0.7, where this library is not yet part of the standard library (#25628). -
using Compat.Distributed
is provided on versions older than 0.7, where this library is not yet part of the standard library (#24443). -
using Compat.Pkg
is provided on versions older than 0.7, where this library is not yet part of the standard library (#25705). Note thatCompat.Pkg
will point to the new package manager on 0.7 which does not have a fully compatible API with the old package manager. -
using Compat.InteractiveUtils
is provided on versions older than 0.7, where this library is not yet part of the standard library (#25780). -
using Compat.LibGit2
is provided on versions older than 0.7, where this library is not yet part of the standard library (#25706). -
using Compat.UUIDs
is provided on versions older than 0.7, where this library is not yet part of the standard library (#25819). -
using Compat.Markdown
is provided on versions older than 0.7, where this library is not yet part of the standard library (#25738). -
using Compat.Sockets
is provided on versions older than 0.7, where this library is not yet part of the standard library (#25935) -
using Compat.Statistics
is provided on versions older than 0.7, where this library is not yet part of the standard library (#27834).
-
@views
takes an expression and converts all slices to views (#20164), while@view
(#16564) converts a single array reference to a view (#20164). -
@__dot__
takes an expression and converts all assignments, function calls, and operators to their broadcasting "dot-call" equivalents (#20321). In Julia 0.6, this can be abbreviated@.
, but that macro name does not parse in earlier Julia versions. For this to work in older versions of Julia (prior to 0.5) that don't have dot calls, you should instead use@dotcompat
, which combines the@__dot__
and@compat
macros. -
normalize
andnormalize!
, normalizes a vector with respect to the p-norm (#13681) -
redirect_stdout
,redirect_stderr
, andredirect_stdin
take an optional function as a first argument,redirect_std*(f, stream)
, so that one may usedo
block syntax (as first available for Julia 0.6) -
unsafe_get
returns the:value
field of aNullable
object without any null-check and has a generic fallback for non-Nullable
argument (#18484) -
isnull
has a generic fallback for non-Nullable
argument -
transcode
converts between UTF-xx string encodings in Julia 0.5 (as a lightweight alternative to the LegacyStrings package) (#17323) -
>:
, a supertype operator for symmetry withissubtype
(A >: B
is equivalent toB <: A
), can be used in 0.5 and earlier (#20407). -
iszero(x)
efficiently checks whetherx == zero(x)
(including arrays) can be used in 0.5 and earlier (#19950). -
.&
and.|
are short syntax forbroadcast(&, xs...)
andbroadcast(|, xs...)
(respectively) in Julia 0.6 (only supported on Julia 0.5 and above) (#17623) -
Compat.isapprox
withnans
keyword argument (#20022) -
Compat.readline
withkeep
keyword argument (#25646) -
Compat.eachline
withkeep
keyword argument (#25646) -
Compat.readuntil
withkeep
keyword argument (#25646) -
take!
method forTask
s since some functions now returnChannel
s instead ofTask
s (#19841) -
The
isabstract
,parameter_upper_bound
,typename
reflection methods were added in Julia 0.6. This package re-exports these from theCompat.TypeUtils
submodule. On earlier versions of julia, that module contains the same functions, but operating on the pre-0.6 type system representation. -
broadcast
is supported on tuples of the same lengths on 0.5. (#16986) -
zeros
andones
support an interface the same assimilar
(#19635) -
convert
can convert between differentSet
types on 0.5 and below. (#18727) -
isassigned(::RefValue)
is supported on 0.5 and below. (#18082) -
unsafe_trunc(::Type{<:Integer}, ::Integer)
is supported on 0.5. (#18629) -
bswap
is supported forComplex
arguments on 0.5 and below. (#21346) -
Compat.invokelatest
is equivalent toBase.invokelatest
in Julia 0.6, but works in Julia 0.5+, and allows you to guarantee that a function call invokes the latest version of a function (#19784). -
Compat.invokelatest
supports keywords (#22646). -
Compat.StringVector
is supported on 0.5 and below. On 0.6 and later, it aliasesBase.StringVector
. This function allocates aVector{UInt8}
whose data can be made into aString
in constant time; that is, without copying. On 0.5 and later, useString(...)
with the vector allocated byStringVector
as an argument to create a string without copying. Note that if 0.4 support is needed,Compat.UTF8String(...)
should be used instead. (#19449) -
@__MODULE__
is aliased tocurrent_module()
for Julia versions 0.6 and below. Versions ofBase.binding_module
,expand
,macroexpand
, andinclude_string
were added that accept a module as the first argument. (#22064) -
Cmd
elements can be accessed as if theCmd
were an array of strings for 0.6 and below (#21197). -
Val(x)
constructsVal{x}()
. (#22475) -
The
reshape
andntuple
APIs are extended to supportVal{x}()
arguments on 0.6 and below. -
logdet
forNumber
s (#22629). -
fieldcount
is equivalent tonfields
for Julia versions 0.6 and below and is used to determine the number of fields in a data type (#22350). -
There are versions of
InexactError
,DomainError
, andOverflowError
that take the same arguments as introduced in Julia 0.7-DEV (#20005, #22751, #22761). -
Base.rtoldefault
how takes a third parameteratol
. The two argument form is deprecated in favor of the three arguments form withatol=0
. -
The
corrected
optional argument ofcov
becomes a keyword argument ofCompat.Statistics.cov
(#21709). -
isequal
,==
andin
have one argument "curried" forms. For exampleisequal(x)
returns a function that compares its arguments tox
usingisequal
(#26436). -
*(::Union{Char,AbstractString},::Union{Char,AbstractString})
concatenation. (#22512) -
diagm
andspdiagm
accept pairs mapping diagonals to vectors (#24047, #23757) -
Constructors for
Matrix{T}
,Array{T}
, andSparseMatrixCSC{T}
fromUniformScaling
(#24372, #24657) -
Constructor for
Matrix
fromUniformScaling
(#24372, #24657). -
UndefInitializer
andundef
with correspondingArray
constructors (#24652, #26316). -
@compat finalizer(func, obj)
with the finalizer to run as the first argument and the object to be finalized as the second (#24605). -
IOContext
accepting key-valuePair
s (#23271). -
pairs
for iterating over key-valuePair
s (#22907). -
get
do-block syntax supported when usingENV
(#23412). -
Some{T}
wrapsT
to signify that a result ofT<:Void
is expected (#23642). -
replace
accepts a pair of pattern and replacement, with the number of replacements as a keyword argument (#25165). -
CartesianIndices
andLinearIndices
types represent cartesian and linear indices of an array (respectively), and indexing such objects allows translating from one kind of index to the other (#25113). -
codeunits(s)
returns an array-like view of theUInt8
code units of a string andncodeunits(s)
returns the number of code units (#25241).codeunit(s)
returns the type of the code units ofs
(#24999). -
thisind(s, i)
returns the character index for codeuniti
(#24414). -
Three-argument methods
prevind(s,i,n)
,nextind(s,i,n)
(#23805), andlength(s,i,j)
(#24999); the latter two replacechr2ind
andind2chr
in Julia 0.7, respectively. -
printstyled
prints to a given stream optionally in color and/or bolded (#25522). -
Dates.Period
rounding (e.g.,round(Dates.Hour(36), Dates.Day, RoundNearestTiesUp) == Dates.Day(2)
(#24182). -
firstindex
to obtain the first index of an iterable (#25458). -
Compat.names
supporting keyword arguments forall
andimported
(#25647). -
Compat.IOBuffer
supporting keyword arguments (#25873). -
Compat.range
supporting keyword arguments (#25896). -
Compat.trunc
,Compat.floor
,Compat.ceil
,Compat.round
, take a keyword argument forbase
anddigits
,Compat.round
also takessigdigits
(#26156, #26670). -
Compat.mv
andCompat.cp
withforce
keyword argument (#26069). -
Compat.accumulate
,Compat.accumulate!
,Compat.all
,Compat.any
,Compat.cumprod
,Compat.cumprod!
,Compat.cumsum
,Compat.cumsum!
,Compat.findmax
,Compat.findmin
,Compat.mapreduce
,Compat.maximum
,Compat.Statistics.mean
,Compat.Statistics.median
,Compat.minimum
,Compat.prod
,Compat.reduce
,Compat.sort
, andCompat.sum
withdims
keyword argument (#25989,#26369). -
Compat.mapreduce
andCompat.reduce
withinit
keyword argument (#27711). -
selectdim
to obtain a view of an array with a specified index for a specified dimension (#26009). -
squeeze
withdims
as keyword argument (#26660). -
Single-argument
permutedims(x)
for matrices and vectors (#24839). -
fetch
forTask
s (#25940). -
Compat.qr
takespivot
as aVal
instance (#22475). -
Compat.Sys.which
andCompat.Sys.isexecutable
(#26559, #27298). -
Compat.rmul!
provides a subset of the functionality ofLinearAlgebra.rmul!
for use with Julia 0.6 (#25701, #25812). -
isbits(t::Type)
is nowisbitstype(t)
(#26850). -
something
to get the first argument different fromnothing
, unwrapping those of theSome
type (#27258). -
mapslices
withdims
keyword argument (#27828).
-
Display
is nowAbstractDisplay
(#24831). -
reprmime(mime, x)
is nowrepr(mime, x)
(#25990) andmimewritable
is nowshowable
(#26089). -
$
is nowxor
or⊻
(#18977) -
num
andden
are nownumerator
anddenominator
(#19246) -
takebuf_array
is now a method oftake!
.takebuf_string(io)
becomesString(take!(io))
(#19088) -
is_apple
,is_bsd
,is_linux
,is_unix
, andis_windows
are nowSys.isapple
,Sys.isbsd
,Sys.islinux
,Sys.isunix
, andSys.iswindows
, respectively. These are available in theCompat.Sys
submodule. (#22182) -
readstring
is replaced by methods ofread
. (#22864)read(::IO, ::Type{String})
,read(::AbstractString, ::Type{String})
, andread(::AbstractCmd, ::Type{String})
are defined for 0.6 and below. -
Range
is nowAbstractRange
(#23570) -
select
* functions (select
,select!
,selectperm
,selectperm!
) are renamed topartialsort
* (partialsort
,partialsort!
,partialsortperm
,partialsortperm!
) (#23051) -
ctranspose
andctranspose!
are nowadjoint
andadjoint!
(#23235) -
Math constants (
π
,pi
,e
,γ
,eulergamma
,catalan
,φ
,golden
) are moved to theMathConstants
module (available asCompat.MathConstants
). The name exported fromBase
fore
is changed toℯ
. (#23427) -
IntSet
is nowBitSet
(#24282) -
Complex32
,Complex64
, andComplex128
are nowComplexF16
,ComplexF32
, andComplexF64
, respectively (#24647). -
JULIA_HOME
is nowSys.BINDIR
, available in theCompat.Sys
submodule. (#25102) -
Associative
is nowAbstractDict
(#25012). -
indices
is nowaxes
(#25057). This function is not exported from Compat to avoid conflicts with AxisArrays and other such packages. -
Void
is nowNothing
with an aliasCvoid
for C interop (#25162). -
unshift!
andshift!
are nowpushfirst!
andpopfirst!
(#25100). -
Base.IteratorSize
andBase.IteratorEltype
are available asCompat.IteratorSize
andCompat.IteratorEltype
(#25402). -
copy!
andunsafe_copy!
are nowcopyto!
andunsafe_copyto!
(#24808). -
contains(haystack, needle)
is nowoccursin(needle, haystack)
(#26283).occursin
also has a new method forChar
needles (#22435). -
ismatch(r::Regex, str::AbstractString, offset=0)
is nowoccursin(r, str)
andoccursin(r, str, offset = offset)
respectively (#24673,#26283). -
ipermute!
is nowinvpermute!
(#25168). -
module_parent
,Base.function_module
, andBase.datatype_module
are now methods of a new function calledparentmodule
(#25629). -
module_name
,Base.function_name
, andBase.datatype_name
are now methods of a new function callednameof
(#25622). -
find
is nowfindall
(#25545). -
search
is nowfindfirst
/findnext
andrsearch
is nowfindlast
/findprev
, sometimes combined withisequal
orin
(#24673, #26436). -
Compat.findfirst
,Compat.findnext
,Compat.findlast
andCompat.findprev
, returnnothing
when no match is found (rather than0
or0:-1
) as on Julia 0.7 (#24673, #26149). -
findin(a, b)
is nowfindall(in(b), a)
(#24673). -
indmin
andindmax
are nowargmin
andargmax
, respectively (#25654). -
Compat.indexin
accepts any iterable as first argument, returnsnothing
(rather than0
) for entries with no match and gives the index of the first (rather than the last) match (#25662, #25998). -
isabstract
andisleaftype
are nowisabstracttype
andisconcretetype
, respectively (#23666, #25496). -
gc
andgc_enable
are nowGC.gc
andGC.enable
, respectively (#25616). -
endof
is nowlastindex
(#25458). (Note thatlastindex(A, n)
is not supported.) -
nb_available
is nowbytesavailable
(#25634). -
method_exists
is nowhasmethod
(#25615). -
object_id
is nowobjectid
(#25615). -
DevNull
,STDIN
,STDOUT
andSTDERR
are nowdevnull
,stdin
,stdout
andstderr
respectively (#25959). -
LinSpace
is nowLinRange
(#25896). -
isupper
,islower
,ucfirst
andlcfirst
are nowisuppercase
,islowercase
,uppercasefirst
andlowercasefirst
(#26442). -
Compat.split
andCompat.rsplit
acceptkeepempty
keyword argument ifsplitter
is given as second argument (#26634) -
isalpha
is nowisletter
(#27077). -
cfunction
is now@cfunction
(#26486). -
Unicode.isnumeric
is now available asisnumeric
(#25479). -
vecnorm
andvecdot
are nowCompat.norm
andCompat.dot
, respectively, while the oldnorm(A::AbstractMatrix, p=2)
is nowCompat.opnorm
(#27401).import Compat: ⋅
to getCompat.dot
as the binary operator⋅
. -
atan2
is now a 2-argument method ofatan
(#27253). -
realmin
andrealmax
are nowfloatmin
andfloatmax
(#28302)
-
@__DIR__
has been added (#18380) -
@vectorize_1arg
and@vectorize_2arg
are deprecated on Julia 0.6 in favor of the broadcast syntax (#17302).Compat.@dep_vectorize_1arg
andCompat.@dep_vectorize_2arg
are provided so that packages can still provide the deprecated definitions without causing a depwarn in the package itself before all the users are upgraded.Packages are expected to use this until all users of the deprecated vectorized function have migrated. These macros will be dropped when the support for
0.6
is dropped fromCompat
. -
@nospecialize
has been added (#22666). -
The logging macros
@error
,@warn
,@info
and@debug
can be used asCompat.@error
,Compat.@warn
,Compat.@info
andCompat.@debug
on Julia 0.6 (#24490). Note that the behavior do not mirror the logging macros in Julia 0.7, instead on Julia 0.6:- Messages are printed to
STDERR
(likeinfo
andwarn
on Julia 0.6) and not to a dedicated logging stream. - The loglevel can not be controlled, but
Compat.@debug
messages can be turned on/off by callingCompat.enable_debug(true/false)
. - Extra metadata sent to the macros are ignored.
As an alternative, see the MicroLogging.jl package for a logging interface similar to the one in Julia 0.7.
- Messages are printed to
-
On versions of Julia that do not contain a Base.Threads module, Compat defines a Threads module containing a no-op
@threads
macro. -
The
Expr(:macrocall)
has an extra initial argument__source__
, which can be tested for withCompat.macros_have_sourceloc
.
Compat.AbstractDateTime
is an alias forCompat.Dates.AbstractDateTime
as of (#25227) andCompat.Dates.TimeType
prior to that.
One of the most important rules for Compat.jl
is to avoid breaking user code
whenever possible, especially on a released version.
Although the syntax used in the most recent Julia version
is the preferred compat syntax, there are cases where this shouldn't be used.
Examples include when the new syntax already has a different meaning
on previous versions of Julia, or when functions are removed from Base
Julia and the alternative cannot be easily implemented on previous versions.
In such cases, possible solutions are forcing the new feature to be used with
qualified name in Compat.jl
(e.g. use Compat.<name>
) or
reimplementing the old features on a later Julia version.
If you're adding additional compatibility code to this package, the contrib/commit-name.sh
script in the base Julia repository is useful for extracting the version number from a git commit SHA. For example, from the git repository of julia
, run something like this:
bash $ contrib/commit-name.sh a378b60fe483130d0d30206deb8ba662e93944da
0.5.0-dev+2023
This prints a version number corresponding to the specified commit of the form
X.Y.Z-aaa+NNNN
, and you can then test whether Julia
is at least this version by VERSION >= v"X.Y.Z-aaa+NNNN"
.
One of the most frequent problems package developers encounter is finding the right
version of Compat
to add to their REQUIRE. This is meant to be a guide on how to
specify the right lower bound.
-
Find the appropriate fix needed for your package from the
Compat
README. Every function or feature added toCompat
is documented in its README, so you are guaranteed to find it. -
Navigate to the blame page of the README by clicking on the README file on GitHub, and then clicking on the
blame
button which can be found in the top-right corner. -
Now find your fix, and then find the corresponding commit ID of that fix on the left-hand side. Click on the commit ID. This navigates to a page which recorded that particular commit.
-
On the top pane, you should find the list of the tagged versions of Compat that includes this fix. Find the minimum version from there.
-
Now specify the correct minimum version for Compat in your REQUIRE file by
Compat <version>