Compatibility across Julia versions

compatibility, julia


Compat Package for Julia

Build Status Build status

Compat Compat

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 ...Julia master syntax...

wherever you want to use syntax that differs in the latest Julia master (the development version of Julia).

Supported syntax

Currently, the @compat macro supports the following syntaxes:

  • @compat foo.:bar - foo.(:bar) in 0.4 (#15032).

  • @compat f.(args...) - broadcast(f, args...) in 0.4 (#15032).

  • @compat (a::B{T}){T}(c) = d - the Julia 0.5-style call overload.

  • @compat Dict(foo => bar, baz => qux) - type-inferred Dict construction. (Also works for DataStructures.OrderedDict)

  • @compat Dict{Foo,Bar}(foo => bar, baz => qux) - type-declared Dict construction. (Also works for DataStructures.OrderedDict)

  • @compat split(str, splitter; keywords...) - the Julia 0.4-style keyword-based split function

  • @compat rsplit(str, splitter; keywords...) - the Julia 0.4-style keyword-based rsplit function

  • @compat Float64(x), @compat UInt8(x), - the Julia 0.4-style numeric types constructor.

  • @compat Tuple{foo, bar} - Julia 0.4-style tuple types.

  • @compat chol(A, Val{:U}) - Julia 0.4 type-stable cholesky factorizations (will not be type-stable on 0.3)

  • @compat f(t::Timer) - mimic the Julia 0.4 Timer class

  • @compat Vector{Int}(), @compat Vector{UInt8}(n), @compat Array{Float32}(2,2) - Julia 0.4-style array constructors.

  • @compat Void - Nothing on 0.3 (Ptr{Void} is not changed).

  • @compat Union{args...} - Union(args...) on 0.3. #11432

  • @compat withenv(f, "a" => a, "b" => b...) on 0.3.

Type Aliases

  • String has undergone multiple changes: in julia 0.3 it was an abstract type and then got renamed to AbstractString; later, ASCIIString and UTF8String got merged into a concrete type, String.

    For packages that still need ASCIIString or UTF8String on julia 0.4 and want to avoid the deprecation warning on julia 0.5, use Compat.ASCIIString and Compat.UTF8String instead. Note that Compat.ASCIIString does not guarantee isascii on julia 0.5. Use isascii to check if the string is pure ASCII if needed.

  • bytestring has been replaced in all cases with additional String construction methods; for 0.3 compatibility, the usage involves replacing bytestring(args...) with @compat String(args...)

  • typealias AbstractString String - String has been renamed to AbstractString #8872

  • typealias AbstractFloat FloatingPoint - FloatingPoint has been renamed to AbstractFloat #12162

  • typealias AssertionError ErrorException - AssertionError was introduced in #9734; before @assert threw an ErrorException

  • For all unsigned integer types to their equivalents with uppercase I. #8907

  • Cstring and Cwstring for Ptr{UInt8} and Ptr{Cwchar_t}, respectively: these should be used for passing NUL-terminated strings to ccall. (In Julia 0.4, using these types also checks whether the string has embedded NUL characters #10994.)

  • typealias Irrational MathConst - MathConst has been renamed to Irrational #11922

  • typealias UDPSocket UdpSocket - UdpSocket has been renamed to UDPSocket #8175

  • typealias Base64EncodePipe Base64Pipe - Base64Pipe has been renamed to Base64EncodePipe #9157

  • typealias OutOfMemoryError MemoryError - MemoryError has been renamed to OutOfMemoryError #10503

New functions

  • eachindex, as in for i in eachindex(A), can be used in julia 0.3. This is the recommended way to iterate over each index in an AbstractArray. On julia 0.3 eachindex just returns 1:length(A), but in julia 0.4 it can return a more sophisticated iterator.

  • isdiag, which tests whether a matrix is diagonal, can be used in julia 0.3.

  • keytype and valtype, which return key and value type of Associative type, can be used in julia 0.3.

  • tryparse, which is a variant on Base.parse that returns a Nullable, can be used in julia 0.3.

  • fma(x,y,z) and muladd(x,y,z) can be used in Julia 0.3 for x*y+z.

  • Timer(timeout::Real, repeat::Real=0.0) and Timer(cb::Function, timeout::Real, repeat::Real=0.0) allow julia 0.4-style Timers to be constructed and used.

  • __precompile__(iscompiled::Bool) and include_dependency(path::AbstractString) allow Julia 0.4 precompilation information to be provided (with no effect in earlier versions). (However, to enable precompiling in 0.4, it is better to explicitly put VERSION >= v"0.4.0-dev+6521" && __precompile__() before your module statement, so that Julia knows to precompile before anything in your module is evaluated.)

  • isapprox(A, B) for arrays (JuliaLang/julia#12472), and synonyms (U+2248, LaTeX \approx) and (U+2249, LaTeX \napprox) for isapprox and !isapprox, respectively.

  • withenv can be used in julia 0.3 (see the 0.4 docs). Note that you must prepend calls to withenv with @compat if you'd like to use it with the => syntax.

  • foreach, similar to map but when the return value is not needed (#13744).

  • walkdir, returns an iterator that walks the directory tree of a directory. (#13707)

Renamed functions

  • itrunc, iround, iceil, ifloor are now accessed via trunc(T, x), etc. (#9133). Truncated conversions between integer types are now n % T (#8646).

  • Base.Random.randmtzig_exprnd is now randexp #9144

  • sizehint is now sizehint! #9278

  • Base.IPv4 and Base.IPv6 can now accept Strings as constructor arguments #9346

  • randbool() is now rand(Bool) and randbool([dims]) is now bitrand([dims]) #9569

  • beginswith is now startswith #9583

  • |>, >>, .>, and .>> are now pipeline (#10211 and #12739)

  • names(::DataType) is now renamed to fieldnames #10332

  • parseint and parsefloat are now parse(T, ...) #10543; along the same line BigFloat(s::String) is now parse(BigFloat,s) #10955.

  • convert(::Ptr{T}, x) is now Base.unsafe_convert #9986. Compat provides an unexported Compat.unsafe_convert method that is aliased to Base.convert on Julia 0.3 and Base.unsafe_convert on Julia 0.4.

  • gc_enable() is now gc_enable(true) and gc_disable() is now gc_enable(false) #11647

  • base64 is now base64encode #9157

  • super is now supertype #14338

  • qr(A, pivot=b) is now qr(A, Val{b}), likewise for qrfact and qrfact!

  • readall and readbytes are now readstring and read #14660

  • get_bigfloat_precision is now precision(BigFloat), set_precision is setprecision and with_bigfloat_precision is now also setprecision #13232

  • get_rounding is now rounding. set_rounding and with_rounding are now setrounding #13232

  • Base.tty_size (which was not exported) is now displaysize in Julia 0.5.

  • Compat.LinAlg.checksquare #14601

  • issym is now issymmetric #15192

  • istext is now istextmime #15708

  • symbol is now Symbol #16154; use @compat Symbol(...) if you need Julia 0.3 compatibility.

  • write(::IO, ::Ptr, len) is now unsafe_write #14766.

New macros

  • @static has been added #16219.

  • @inline and @noinline have been added. On 0.3, these are "no-ops," meaning they don't actually do anything.

  • @functorize (not present in any Julia version) takes a function (or operator) and turns it into a functor object if one is available in the used Julia version. E.g. something like mapreduce(Base.AbsFun(), Base.MulFun(), x) can now be written as mapreduce(@functorize(abs), @functorize(*), x), and f(::Base.AbsFun()) as f(::typeof(@functorize(abs))), to work across different Julia versions. Func{1} can be written as supertype(typeof(@functorize(abs))) (and so on for Func{2}), which will fall back to Function on Julia 0.5.

Other changes

  • Dict(ks, vs) is now Dict(zip(ks, vs)) #8521

  • Libc and dynamic library-related functions have been moved to the Libc and Libdl modules #10328

  • zero(Ptr{T}) is now Ptr{T}(0) #8909

  • The unexported macro Base.@math_const was renamed to Base.@irrational, accessible as Compat.@irrational on either 0.3 or 0.4 #11922

  • remotecall, remotecall_fetch, remotecall_wait, and remote_do have the function to be executed remotely as the first argument in Julia 0.5. Loading Compat defines the same methods in older versions of Julia. #13338

  • Base.FS is now Base.Filesystem #12819. Compat provides an unexported Compat.Filesystem module that is aliased to Base.FS on Julia 0.3 and 0.4 and Base.Filesystem on Julia 0.5.

  • mktemp and mktempdir now have variants which take a function as their first argument for automated cleanup. #9017

  • cov and cor don't allow keyword arguments anymore. Loading Compat defines compatibility methods for the new API. #13465

  • On versions of Julia that do not contain a Base.Threads module, Compat defines a Threads module containing a no-op @threads macro.

  • Base.SingleAsyncWork is now Base.AsyncCondition Compat provides an unexported Compat.AsyncCondition type that is aliased to Base.SingleAsyncWork on Julia 0.3 and 0.4 and Base.AsyncCondition on Julia 0.5.

  • repeat now accepts any AbstractArray #14082: Compat.repeat supports this new API on Julia 0.3 and 0.4, and calls Base.repeat on 0.5.

  • OS_NAME is now Sys.KERNEL. OS information available as is_apple, is_bsd, is_linux, is_unix, and is_windows. 16219

New types

Developer tips

If you're adding additional compatibility code to this package, the bin/ script 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 $ /path/to/Compat/bin/ a378b60fe483130d0d30206deb8ba662e93944da

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".